<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23574449</id><updated>2012-01-26T12:10:07.315+01:00</updated><category term='Inżynieria Oprogramowania'/><category term='ForceSeat_GT'/><category term='ciekawostki'/><category term='inne'/><category term='ruby on rails'/><category term='ubuntu'/><category term='JavaScript'/><category term='mysql'/><category term='git'/><category term='LaTeX'/><category term='netbeans'/><category term='sztuczna inteligencja'/><title type='text'>Michał Stanek - Ruby on Rails i inne ...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>63</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23574449.post-7652896840915036385</id><published>2009-10-25T19:32:00.000+01:00</published><updated>2009-10-25T19:32:00.062+01:00</updated><title type='text'>Szablony dokumentów dla metodyki Rational Unified Process (RUP)</title><content type='html'>&lt;h2&gt;Model biznesowy&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNzBzcXFxMnI1cA"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Software Architecture Document&lt;/h2&gt;&lt;br /&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNjhkNzQyZG5ocg"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Wizja systemu&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNjVmcW5zY2JoYw"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Opis Use Casa&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNTdmaDdqaDRnaw"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Słownik biznesowy&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNjZrNXIza3JmcA"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Słownik systemowy&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNjJkNDY4YzJocw"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Raport spotkania projektowego&lt;/h2&gt;&lt;iframe width="620" height="170" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://docs.google.com/embeddedtemplate?id=0ASNNy7X6doajZGdqNzN0azdfNjdmcjRxcmZqMw"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7652896840915036385?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7652896840915036385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7652896840915036385' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7652896840915036385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7652896840915036385'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/10/szablony-dokumentow-dla-metodyki.html' title='Szablony dokumentów dla metodyki Rational Unified Process (RUP)'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7949719187078871353</id><published>2009-10-24T22:35:00.001+02:00</published><updated>2009-10-24T22:35:49.842+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ForceSeat_GT'/><title type='text'>ForceSeat GT - Film Promocyjny</title><content type='html'>&lt;object height="295" width="480"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/KNuLBTFtSCI&amp;hl=pl&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/KNuLBTFtSCI&amp;hl=pl&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7949719187078871353?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7949719187078871353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7949719187078871353' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7949719187078871353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7949719187078871353'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/10/forceseat-gt-film-promocyjny.html' title='ForceSeat GT - Film Promocyjny'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6783350324425138831</id><published>2009-10-21T19:37:00.006+02:00</published><updated>2009-10-28T22:47:41.951+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ForceSeat_GT'/><title type='text'>ForceSeat GT - 3 DoF Hydraulic Motion Simulator officially announce</title><content type='html'>I am pleased to announce that the first model of the hydraulic simulator was shown to a wider audience&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="http://picasaweb.google.pl/s/c/bin/slideshow.swf" width="400" height="267" flashvars="host=picasaweb.google.pl&amp;captions=1&amp;hl=pl&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.pl%2Fdata%2Ffeed%2Fapi%2Fuser%2Fizmisiek%2Falbumid%2F5395097011506574097%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/AMsbQQLBRKk&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/AMsbQQLBRKk&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6783350324425138831?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6783350324425138831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6783350324425138831' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6783350324425138831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6783350324425138831'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/10/forceseat-gt-3-dof-hydraulic-motion.html' title='ForceSeat GT - 3 DoF Hydraulic Motion Simulator officially announce'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7718664842210994650</id><published>2009-06-08T15:32:00.002+02:00</published><updated>2009-06-08T15:35:18.526+02:00</updated><title type='text'>SVN w Eclipse 3.4.2</title><content type='html'>Wbrew pozorom integracja pluginu SVN w eclipsie zabiera chwilę czasu, ponieważ dostępne w sieci tutoriale dziwnym sposobem nie prowadzą do działającego rozwiązania. &lt;br /&gt;&lt;br /&gt;Instrukcja instalacji:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt; &lt;br /&gt;&lt;br /&gt;&lt;li&gt; Zainstalować SVN Team Provider z: &lt;br /&gt;http://download.eclipse.org/technology/subversive/0.7/update-site/.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; A na koniec sam plugin: &lt;br /&gt;http://www.polarion.org/projects/subversive/download/eclipse/2.0/update-site/&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Powinno działać&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7718664842210994650?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7718664842210994650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7718664842210994650' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7718664842210994650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7718664842210994650'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/06/svn-w-eclipse-342.html' title='SVN w Eclipse 3.4.2'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2831489071445790324</id><published>2009-06-07T20:46:00.003+02:00</published><updated>2009-06-07T20:53:22.330+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Instalacja Google Chrome pod Ubuntu 9.04</title><content type='html'>&lt;pre class="brush: bash"&gt;&lt;br /&gt;sudo gedit /etc/apt/sources.list&lt;br /&gt;&lt;br /&gt;deb http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main&lt;br /&gt;deb-src http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main &lt;br /&gt;&lt;br /&gt;sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xfbef0d696de1c72ba5a835fe5a9bf3bb4e5e17b5&lt;br /&gt;&lt;br /&gt;sudo apt-get update&lt;br /&gt;sudo apt-get install chromium-browser&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2831489071445790324?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2831489071445790324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2831489071445790324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2831489071445790324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2831489071445790324'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/06/instalacja-google-chrome-pod-ubuntu.html' title='Instalacja Google Chrome pod Ubuntu 9.04'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3758500679055184734</id><published>2009-06-05T08:45:00.006+02:00</published><updated>2009-06-05T08:54:18.237+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Edytor LaTeXa pod Ubuntu - gEdit i LaTeX</title><content type='html'>Poniżej opiszę jak zainstalować plugin LaTeXa dla gEdita, efekt końcowy można zobaczyć pod tym &lt;a href="http://live.gnome.org/Gedit/LaTeXPlugin/Screenshots"&gt;adresem&lt;/a&gt;. Instrukcja:&lt;br /&gt;&lt;br /&gt;Zacznijmy od dodania odpowienich repozytoriów:&lt;br /&gt;&lt;pre class="brush: bash"&gt;&lt;br /&gt;sudo gedit /etc/apt/sources.list.d/gedit-latex-plugin.list &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W pliku tym należy wkleić poniższe wiersze:&lt;br /&gt;&lt;pre class="brush: bash"&gt;&lt;br /&gt;deb http://ppa.launchpad.net/ubuntu-it-dev/ubuntu gutsy main&lt;br /&gt;deb-src http://ppa.launchpad.net/ubuntu-it-dev/ubuntu gutsy main&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Uaktualnienie informacji o pakietach oraz instalacja odpowiednich paczek:&lt;br /&gt;&lt;pre class="brush: bash"&gt;&lt;br /&gt;sudo apt-get update&lt;br /&gt;sudo apt-get install texlive-latex-recommended texlive-latex-extra texlive-fonts-extra texlive-humanities texlive-math-extra texlive-pictures&lt;br /&gt;sudo apt-get install rubber gedit-latex-plugin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Kolejnym krokiem będzie uruchomienie plug-inu już w edytorze gEdit. W tym celu należy wejść do menu &lt;span style="font-style:italic;"&gt;Edycja-Preferencje&lt;/span&gt; i wybrać zakładkę &lt;span style="font-style:italic;"&gt;Wtyczki&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3758500679055184734?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3758500679055184734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3758500679055184734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3758500679055184734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3758500679055184734'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/06/edytor-latexa-pod-ubuntu-gedit-i-latex.html' title='Edytor LaTeXa pod Ubuntu - gEdit i LaTeX'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8352416015550968967</id><published>2009-06-03T13:08:00.001+02:00</published><updated>2009-06-03T13:09:23.332+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Install Eclipse 3.4 on Ubuntu 9.04</title><content type='html'>Just follow the instructions given under the following adress:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://zanshin.net/2009/04/25/install-eclipse-ganymede-on-ubuntu-904/"&gt;http://zanshin.net/2009/04/25/install-eclipse-ganymede-on-ubuntu-904/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8352416015550968967?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8352416015550968967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8352416015550968967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8352416015550968967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8352416015550968967'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/06/install-eclipse-34-on-ubuntu-904.html' title='Install Eclipse 3.4 on Ubuntu 9.04'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7722728400569319044</id><published>2009-05-07T23:26:00.007+02:00</published><updated>2009-05-07T23:42:12.571+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ciekawostki'/><title type='text'>Astromenace - gra warta uwagi</title><content type='html'>Dzisiaj trochę z innej beczki, ponieważ post dotyczyć będzie tematów rozrywkowych. A postanowiłem, go napisać ponieważ jak do tej pory ciekawe gry pod Linuxa to jednak rzadkość, więc jeżeli pojawia się coś interesującego myślę że warto o tym napisać. &lt;br /&gt;&lt;br /&gt;Gra nazywa się &lt;a href="http://www.viewizard.com/astromenace/index_linux.php"&gt;Astromenace&lt;/a&gt; i jest strzelanką, w której latamy statkiem i strzelamy do wrogów. Scenariusz podobny do setek innych gier, to co wyróżnia jednak ten tytuł to bardzo starannie wykonana grafika, oraz znany zwłaszcza z gier RPG, mechanizm zdobywania doświadczenia i kupowania coraz to lepszego wyposażenia i pancerzy. &lt;br /&gt;&lt;br /&gt;Poniżej kilka screenów z gry:&lt;br /&gt;&lt;br /&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 188px;" src="http://phorolinux.com/images/2008/03/AstroMenace-menu1-thumb.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 188px;" src="http://phorolinux.com/images/2008/03/AstroMenace1-thumb.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 188px;" src="http://phorolinux.com/images/2008/03/AstroMenace3-thumb.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Instalacja:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Ściągamy &lt;a href="http://www.viewizard.com/download/amenace12.tar.bz2"&gt;spakowaną wersję gry&lt;/a&gt; ze strony producenta - &lt;a href="http://www.viewizard.com/download.php"&gt;link&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rozpakowujemy archiwum (np. &lt;span style="font-style:italic;"&gt;tar jxvf amenace12.tar.bz2&lt;/span&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Uruchamiamy grę (&lt;span style="font-style:italic;"&gt;./game_launcher&lt;/span&gt;)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Uwaga: Do prawidłowego działania gry zainstalowane musimy mieć następujące biblioteki:&lt;br /&gt;libSDL, libopenal, libalut, libogg, libvorbis, libvorbisfile, libjpeg.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7722728400569319044?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7722728400569319044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7722728400569319044' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7722728400569319044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7722728400569319044'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/05/astromenace-gra-warta-uwagi.html' title='Astromenace - gra warta uwagi'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2787780033228636919</id><published>2009-05-04T13:13:00.004+02:00</published><updated>2009-05-30T14:32:49.951+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>GIT - usunięcie plików omyłkowo dodanych do repozytorium</title><content type='html'>Czasami przez omyłkę lub błąd w pliku &lt;span style="font-style:italic;"&gt;.gitignore&lt;/span&gt; do repozytorium dodana może zostać dość spora liczba plików, których byśmy tam nie chcieli. W moim przypadku w repozytorium znajdowała się dość spora liczba plików &lt;span style="font-style:italic;"&gt;*.class&lt;/span&gt;. Poniżej podaję prosty sposób na rozwiązanie takiego problemu:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;&lt;br /&gt;find . -name *.class -print0 | xargs -0 `git rm`&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2787780033228636919?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2787780033228636919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2787780033228636919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2787780033228636919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2787780033228636919'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/05/git-usuniecie-plikow-omykowo-dodanych.html' title='GIT - usunięcie plików omyłkowo dodanych do repozytorium'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8277822177566192722</id><published>2009-05-04T12:59:00.005+02:00</published><updated>2009-05-30T14:36:18.104+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Git - domyślny plik gitignore</title><content type='html'>W przypadku kiedy pracujemy lub tworzymy wiele projektów, które wersjonujemy systemem GIT, konieczne jest wielokrotne tworzenie pliku &lt;span style="font-style:italic;"&gt;.gitignore&lt;/span&gt;, w którym zawarte są reguły dotyczące plików które mają być ignorowane (ewentualnie reguły te wprowadzić można w pliku (&lt;span style="font-style:italic;"&gt;.git/info/exclude&lt;/span&gt;). Jest to dość uciążliwe, na szczęście możemy zdefiniować domyślny plik gitignore dla wszystkich projektów z jakimi pracujemy. Magiczna linijka kodu która to ustawi znajduje się poniżej:&lt;br /&gt;&lt;br /&gt;&lt;pre class="bruch:bash"&gt;&lt;br /&gt;git config --global core.excludesfile ~/.gitignore&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Uwagi: domyślny plik .gitignore znajduje się w katalogu domowym (nic jednak nie stoi na przeszkodze, aby umieścić go gdzie indziej)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8277822177566192722?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8277822177566192722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8277822177566192722' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8277822177566192722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8277822177566192722'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/05/git-domyslny-plik-gitignore.html' title='Git - domyślny plik gitignore'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1147833281198255692</id><published>2009-04-27T21:24:00.003+02:00</published><updated>2009-04-27T21:25:35.643+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ciekawostki'/><title type='text'>Platforma Symylacyjna 3DoF - test sterowania za pomocą kierownicy</title><content type='html'>&lt;center&gt;&lt;br /&gt;&lt;object width="340" height="285"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/XmeVooyez3o&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/XmeVooyez3o&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"&gt;&lt;/embed&gt;&lt;/object&gt; &lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1147833281198255692?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1147833281198255692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1147833281198255692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1147833281198255692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1147833281198255692'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/04/platforma-symylacyjna-3dof-test.html' title='Platforma Symylacyjna 3DoF - test sterowania za pomocą kierownicy'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4477550246664026136</id><published>2009-04-20T14:05:00.006+02:00</published><updated>2009-04-20T14:16:54.969+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ciekawostki'/><title type='text'>Testy prototypu platformy hydraulicznej z trzema stopniami swobody (3 DoF)</title><content type='html'>Poniżej pierwsze filmy z testów platformy hydraulicznej. &lt;br /&gt;&lt;br /&gt;Parametry techniczne:&lt;br /&gt; - Ciśnienie w układzie - regulowane nastawnym zaworem przelewowym od 5 do 20 Bar&lt;br /&gt; - Skok tłoka siłownika: 13 cm&lt;br /&gt; - Mikrokontroler: AVR (Atmega 8)&lt;br /&gt; - Komunikacja z komputerem: USB&lt;br /&gt; - Układ pomiarowy: fotooptyczny&lt;br /&gt; - Ciężar urządzenia: ok 130 kg&lt;br /&gt; - Wydajność pompy: 12 [l/min] (na krućcach przy siłownikach zastosowane dodatkowo dławiki) &lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="340" height="285"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/CMnr1TKedy8&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/CMnr1TKedy8&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="340" height="285"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/xWr_9_lVzUY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/xWr_9_lVzUY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4477550246664026136?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4477550246664026136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4477550246664026136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4477550246664026136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4477550246664026136'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/04/testy-prototypu-platformy-hydraulicznej.html' title='Testy prototypu platformy hydraulicznej z trzema stopniami swobody (3 DoF)'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6862867071120032242</id><published>2009-04-17T12:53:00.029+02:00</published><updated>2009-04-17T13:06:43.209+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Pluginy Ruby on Rails z których najprawdopodobniej będziesz chciał skorzystać</title><content type='html'>Na &lt;a href="http://railslab.newrelic.com/2009/04/01/the-state-of-the-stack-a-ruby-on-rails-benchmarking-report"&gt;RailsLab&lt;/a&gt; w ukazał się ciekawy artykuł, w którym znaleźć możemy zestawienie procentowe projektów wykorzystujących poszczególne wersje Ruby on Rails. Ciekwszym aspektem omawianego artykułu jest jednak zestawienie najczęściej wykorzystywanych pluginów (zrobione w oparciu o dane pochodzące z GitHuba). W pierwszej piątce znajdują się:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://github.com/rails/exception_notification/tree/master"&gt;exception_notification&lt;/a&gt;&lt;/li&gt; &lt;br /&gt;&lt;li&gt;&lt;a href="http://github.com/technoweenie/restful-authentication/tree/master"&gt;restful_authentication&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://github.com/mislav/will_paginate/tree/master"&gt;will_paginate&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://github.com/technoweenie/attachment_fu/tree/master"&gt;attachment_fu&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://github.com/rails/acts_as_list/tree/master"&gt;acts_as_list&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;W dalszej kolejności znajdują się:&lt;br /&gt;&lt;br /&gt;&lt;ol start=6&gt;&lt;br /&gt;&lt;li&gt;hoptoad_notifer&lt;/li&gt; &lt;br /&gt;&lt;li&gt;rspec&lt;/li&gt;&lt;br /&gt;&lt;li&gt;acts_as_tree&lt;/li&gt;&lt;br /&gt;&lt;li&gt;acts_as_state_machine&lt;/li&gt;&lt;br /&gt;&lt;li&gt;auto_complete&lt;/li&gt;&lt;br /&gt;&lt;li&gt;paperclip&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ssl_requirement&lt;/li&gt;&lt;br /&gt;&lt;li&gt;haml&lt;/li&gt;&lt;br /&gt;&lt;li&gt;rspec-rails&lt;/li&gt;&lt;br /&gt;&lt;li&gt;annotate_models&lt;/li&gt;&lt;br /&gt;&lt;li&gt;actice_merchant&lt;/li&gt;&lt;br /&gt;&lt;li&gt;acts_as_taggable_on_steroids&lt;/li&gt;&lt;br /&gt;&lt;li&gt;asset_packer&lt;/li&gt;&lt;br /&gt;&lt;li&gt;calendar_date_select&lt;/li&gt;&lt;br /&gt;&lt;li&gt;jrails&lt;/li&gt;&lt;br /&gt;&lt;li&gt;in_place_editing&lt;/li&gt;&lt;br /&gt;&lt;li&gt;responds_to_parent&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6862867071120032242?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6862867071120032242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6862867071120032242' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6862867071120032242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6862867071120032242'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/04/pluginy-ruby-on-rails-z-ktorych.html' title='Pluginy Ruby on Rails z których najprawdopodobniej będziesz chciał skorzystać'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3317404716524515705</id><published>2009-04-03T13:52:00.003+02:00</published><updated>2009-04-03T13:58:01.224+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Traffic Flow Simulation System based on Cellular Automata</title><content type='html'>Below I have attached videos from my application which simulate car traffic flow. Application use  Cellular Automata to simulate car movements. &lt;br /&gt;&lt;br /&gt;&lt;object width="445" height="364"&gt;&lt;param name="movie" value="http://www.youtube.com/v/nTufvBUhqLo&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/nTufvBUhqLo&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/S7iq-ufSpr8&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/S7iq-ufSpr8&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4h5rpbz-QXY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/4h5rpbz-QXY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/EIQnkXVqib0&amp;hl=pl&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/EIQnkXVqib0&amp;hl=pl&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/JVY5acgibFw&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/JVY5acgibFw&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4h5rpbz-QXY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/4h5rpbz-QXY&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ZFbjFz1DSOE&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ZFbjFz1DSOE&amp;hl=pl&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3317404716524515705?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3317404716524515705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3317404716524515705' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3317404716524515705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3317404716524515705'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/04/traffic-flow-simulation-system-based-on.html' title='Traffic Flow Simulation System based on Cellular Automata'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2062702679758500523</id><published>2009-04-02T16:43:00.005+02:00</published><updated>2009-05-30T14:37:47.416+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Wykorzystanie Helperów w Kontrolerach i Modelu</title><content type='html'>Wykorzystanie dostępnych w Railsach Helperów bezpośrednio w modelu, lub kontrolerach nie jest wspierane bezpośrednio przez środowisko. Przyczyn tego faktu należu upatrywać w chęci zapobiegania wykorzystania kodu Widoku w niższych warstwach, dzięki czemu wzrasta przejrzystość całej aplikacji. Niestety w pewnych specyficznych przypadkach bardzo pomocne staje się wykorzystanie bezpośrednio w modelu którejś z metod np. ActionView::Helpers::TextHelper.&lt;br /&gt;&lt;br /&gt;Poniżej metoda, jaką możemy zastosować aby wywołać helpery (&lt;a href="http://snipplr.com/view/2505/use-helpers-in-controllers-or-models/"&gt;źródło&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Tworzymy plik np. helpery.rb w katalogu 'lib'&lt;br /&gt;&lt;pre class="brush:ruby"&gt;&lt;br /&gt;  def help&lt;br /&gt;    Helper.instance&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Helper&lt;br /&gt;    include Singleton&lt;br /&gt;    include ActionView::Helpers::TextHelper&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Teraz wystarczy w modelu lub kontrollerze dodać nagłówek:&lt;br /&gt;&lt;pre class="brush:ruby"&gt;&lt;br /&gt;require 'lib/helpers'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wywołanie metody helpera sprowadza się wówczas do wywołania:&lt;br /&gt;&lt;pre class="brush:ruby"&gt;&lt;br /&gt;# help.name_of_helper&lt;br /&gt;help.pluralize 10, "person"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2062702679758500523?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2062702679758500523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2062702679758500523' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2062702679758500523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2062702679758500523'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/04/wykorzystanie-helperow-w-kontrolerach-i.html' title='Wykorzystanie Helperów w Kontrolerach i Modelu'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-409165312870297183</id><published>2009-03-17T09:03:00.005+01:00</published><updated>2009-03-17T09:11:33.597+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Szablon pracy magisterskiej w Latex'u</title><content type='html'>Jeżeli komuś miałbym polecać narzędzie w jakim miałby pisać pracę magisterską byłby to zdecydowanie Latex. Niestety potencjalny dyplomant staje przed problemem pełnego skonfigurowania środowiska, tak aby dokument wynikowy był zgodny z normami narzuconymi na jego uczelni.&lt;br /&gt;&lt;br /&gt;Pisząc pracę dyplomową przygotowałem szablon Latexa, uwzględniający wszystkie wymogi edytorskie jakie były narzucona na moim wydziale (Politechnika Wrocławska Wydział Informatyki i Zarządzania). Być może przyda się to komuś jako punkt startu.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.deltasoftware.pl/dokumenty/M_Stanek-szablon_pracy_magisterskiej(latex).7z"&gt;Szablon pracy magisterskiej w Latexu &lt;/a&gt; (750 kB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-409165312870297183?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/409165312870297183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=409165312870297183' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/409165312870297183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/409165312870297183'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/03/szablon-pracy-magisterskiej-w-latexu.html' title='Szablon pracy magisterskiej w Latex&apos;u'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-379999234196968378</id><published>2009-03-13T17:31:00.003+01:00</published><updated>2009-03-17T09:11:04.366+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ciekawostki'/><title type='text'>Liczba Pi z dokładnością do MILIONA liczb po przecinku</title><content type='html'>3.14, a może 3.14159, chyba niewielu z nas potrzebuje z większą dokładnością przybliżać liczbę PI. A co jeśli z jakiegoś powodu potrzebna jest ZDECYDOWANIE większa dokładność, ..., sto miejsc, ..., tysiąc, ...? Teraz możliwe jest już nawet posługiwanie się liczbą Pi o dokładności do jednego MILIONA miejsc po przecinku, wystarczy tylko odwiedzić stronę:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.141592653589793238462643383279502884197169399375105820974944592.com/index314.html"&gt;http://3.141592653589793238462643383279502884197169399375105820974944592.com/index314.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-379999234196968378?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/379999234196968378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=379999234196968378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/379999234196968378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/379999234196968378'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/03/liczba-pi-z-dokadnoscia-do-miliona.html' title='Liczba Pi z dokładnością do MILIONA liczb po przecinku'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8335765205374223775</id><published>2009-03-05T12:48:00.004+01:00</published><updated>2009-04-03T11:57:25.142+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Inteligentne systemy w zarządzaniu ruchem drogowym</title><content type='html'>&lt;a title="View Michal Stanek-Inteligentne Systemy w Zarzadzaniu Ruchem Drogowym on Scribd" href="http://www.scribd.com/doc/13570152/Michal-StanekInteligentne-Systemy-w-Zarzadzaniu-Ruchem-Drogowym" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Michal Stanek-Inteligentne Systemy w Zarzadzaniu Ruchem Drogowym&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_970308049107877" name="doc_970308049107877" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13570152&amp;access_key=key-raj5eit75wugitj5jyp&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13570152&amp;access_key=key-raj5eit75wugitj5jyp&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_970308049107877_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/School-Work/Essays-Theses" style="text-decoration: underline;"&gt;Essays &amp;amp; Theses&lt;/a&gt;              &lt;a href="http://www.scribd.com/browse/School-Work/" style="text-decoration: underline;"&gt;School Work&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/ruch%20drogowy" style="text-decoration: underline;"&gt;ruch drogowy&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/algorytmy%20genetyczne" style="text-decoration: underline;"&gt;algorytmy genetyczne&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8335765205374223775?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8335765205374223775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8335765205374223775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8335765205374223775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8335765205374223775'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/03/inteligentne-systemy-w-zarzadzaniu.html' title='Inteligentne systemy w zarządzaniu ruchem drogowym'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6973874362606667733</id><published>2009-03-02T17:06:00.006+01:00</published><updated>2009-04-03T12:03:39.294+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Wieloagentowa Architektura Rozproszonego Systemu Przetwarzania Zadań z Dynamicznym Równoważeniem Obciążeń</title><content type='html'>&lt;a title="View M Stanek-Wieloagentowa Architektura Rozproszonego Systemu Przetwarzania Zadan z Dynamicznym Rownowazeniem Obciazen on Scribd" href="http://www.scribd.com/doc/13570151/M-StanekWieloagentowa-Architektura-Rozproszonego-Systemu-Przetwarzania-Zadan-z-Dynamicznym-Rownowazeniem-Obciazen" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;M Stanek-Wieloagentowa Architektura Rozproszonego Systemu Przetwarzania Zadan z Dynamicznym Rownowazeniem O...&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_803585766191951" name="doc_803585766191951" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13570151&amp;access_key=key-1ynbzacovyt6chebkl10&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13570151&amp;access_key=key-1ynbzacovyt6chebkl10&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_803585766191951_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/Research/" style="text-decoration: underline;"&gt;Research&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/systemy%20wieloagentowe" style="text-decoration: underline;"&gt;systemy wieloagentow&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/sztuczna%20inteligencja" style="text-decoration: underline;"&gt;sztuczna inteligencj&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6973874362606667733?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6973874362606667733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6973874362606667733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6973874362606667733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6973874362606667733'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/03/wieloagentowa-architektura.html' title='Wieloagentowa Architektura Rozproszonego Systemu Przetwarzania Zadań z Dynamicznym Równoważeniem Obciążeń'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-279533919760164045</id><published>2009-03-02T16:57:00.004+01:00</published><updated>2009-04-03T12:06:21.311+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Predykcja danych w szeregach czasowych</title><content type='html'>&lt;a title="View M Stanek-Predykcja Danych w Szeregach Czasowych on Scribd" href="http://www.scribd.com/doc/13570148/M-StanekPredykcja-Danych-w-Szeregach-Czasowych" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;M Stanek-Predykcja Danych w Szeregach Czasowych&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_217876861991490" name="doc_217876861991490" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="450" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13570148&amp;access_key=key-2f2n2h4oaj5cna4bnkp&amp;page=1&amp;version=1&amp;viewMode=book"&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;            &lt;param name="mode" value="book"&gt;       &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13570148&amp;access_key=key-2f2n2h4oaj5cna4bnkp&amp;page=1&amp;version=1&amp;viewMode=book" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_217876861991490_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle" mode="book" height="500" width="450"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/School-Work/" style="text-decoration: underline;"&gt;School Work&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/Draft%20Research" style="text-decoration: underline;"&gt;Draft Research&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/sztuczna%20inteligencja" style="text-decoration: underline;"&gt;sztuczna inteligencj&lt;/a&gt;       &lt;/div&gt;  &lt;div style="display:none"&gt; &lt;br /&gt;Predykcja danych w szeregach czasowych  1/42  Predykcja danych w szeregach czasowych na przykładzie predykcji cen akcji giełdowych spółki KGHM Polska Miedź S.A. Piotr Kupczyk (pkk@wp.pl) Michał Stanek (michal.stanek@student.pwr.wroc.pl)  13 czerwca 2005  Abstract: Prognozowanie przyszłych wartości akcji giełdowych jest marzeniem wielu osób. Artykuł przedstawia wykorzystanie hybrydowego rozwiązania bazującego na sieciach neuronowych oraz analizie statystycznej podczas predykcji danych w szeregach czasowych na przykładzie predykcji cen akcji KGHM Polska Miedź S.A. W dokumencie zostały szczegółowo omówione dwie architektury sieci neuronowych jedna bazująca na znakowej reprezentacji wartości funkcji druga bazująca na jej wartościach rzeczywistych. Na koniec omówiono rozwiązanie hybrydowe łączące  Predykcja danych w szeregach czasowych moŜliwości tych sieci z predykcją opartą na funkcji regresji. Zostały omówione otrzymane wyniki oraz przedstawione moŜliwe ulepszenia.  2/42  Predykcja danych w szeregach czasowych  3/42  Spis treści: Wstęp.............................................................................................................................. 6 Dane ............................................................................................................................... 7 Predykcja ...................................................................................................................... 11 Metody predykcji ......................................................................................................... 13 Sieć neuronowa numeryczna............................................................................................ 13 Sieć neuronowa znakowa ................................................................................................. 15 Regresja ............................................................................................................................ 17 5. Eksperymenty............................................................................................................... 18 1. Badanie..................................................................................................................... 18 6. Wnioski ........................................................................................................................ 41 7. Literatura ...................................................................................................................... 42 1. 2. 3. 4.  Spis tabel: Tabela 1. Dane giełdowe dla akcji spółki KGHM. .................................................................... 7 Tabela 2. Dane po preprocessingu. ............................................................................................ 7 Tabela 3. Błąd predykcji sieci liczbowej dla zbioru uczącego. ............................................... 19 Tabela 4. Liczba epok uczących sieci numerycznej dla zbioru testowego. ............................. 19  Spis rysunków: Rysunek 1. Dane giełdowe spółki KGHM................................................................................. 8 Rysunek 2. Wykres funkcji liniowej. ......................................................................................... 9 Rysunek 3. Wykres funkcji kwadratowej................................................................................... 9 Rysunek 4. Funkcja okresowa sin(x) + a ................................................................................. 10 Rysunek 5. Funkcja okresowa sin(x) + x ................................................................................ 10 Rysunek 6. Związek pomiędzy wartościami funkcji predykowanymi i rzeczywistymi. ......... 11 Rysunek 7. Idea predykcji krótko okresowej. .......................................................................... 12 Rysunek 8. Idea predykcji długo okresowej. ........................................................................... 12 Rysunek 9. Schemat blokowy hybrydy.................................................................................... 13 Rysunek 10. Schemat sieci numerycznej. ................................................................................ 14 Rysunek 11. Schemat konwersji danych dla sieci znakowej. .................................................. 15 Rysunek 12. Budowa sieci znakowej. ...................................................................................... 16 Rysunek 13. Przykład przybliŜenia funkcji wielomianem drugiego stopnia. .......................... 17 Rysunek 14. Przykład przybliŜenia funkcji wielomianem trzeciego stopnia........................... 17 Rysunek 15. Przykład przybliŜenia funkcji wielomianem czwartego stopnia......................... 17 Rysunek 16. Przykład przybliŜenia funkcji wielomianem piątego stopnia.............................. 17 Rysunek 17.Przykład przybliŜenia funkcji wielomianem szóstego stopnia. ........................... 17 Rysunek 18. Wykres zaleŜności błędu sieci numerycznej od ilości epok uczących................ 18 Rysunek 19. Wykres zaleŜności błędu sieci znakowej od ilości epok uczących. .................... 18 Rysunek 20. Funkcja linowa. ................................................................................................... 21 Rysunek 21. Predykcja na zbiorze uczącym. ........................................................................... 21 Rysunek 22. Predykcja krokowa na zbiorze testowym............................................................ 22 Rysunek 23. Predykcja ciągła na zbiorze testowym. ............................................................... 22  Predykcja danych w szeregach czasowych  4/42  Rysunek 24. Predykcja na zbiorze uczącym. ........................................................................... 22 Rysunek 25 Predykcja krokowa na zbiorze testowym............................................................. 22 Rysunek 26 Predykcja ciągła na zbiorze testowym. ................................................................ 22 Rysunek 27. Predykcja na zbiorze uczącym. ........................................................................... 23 Rysunek 28. Predykcja krokowa na zbiorze testowym............................................................ 23 Rysunek 29. Predykcja na zbiorze uczącym. ........................................................................... 23 Rysunek 30. Predykcja krokowa na zbiorze testowym............................................................ 23 Rysunek 31. Funkcja kwadratowa............................................................................................ 24 Rysunek 32. Predykcja na zbiorze uczącym. ........................................................................... 24 Rysunek 33. Predykcja krokowa na zbiorze testowym............................................................ 25 Rysunek 34. Predykcja ciągła na zbiorze testowym. ............................................................... 25 Rysunek 35. Predykcja na zbiorze uczącym. ........................................................................... 25 Rysunek 36. Predykcja krokowa na zbiorze testowym............................................................ 25 Rysunek 37. Predykcja ciągła na zbiorze testowym. ............................................................... 25 Rysunek 38. Predykcja na zbiorze uczącym. ........................................................................... 26 Rysunek 39. Predykcja krokowa na zbiorze testowym............................................................ 26 Rysunek 40. Predykcja na zbiorze uczącym. ........................................................................... 26 Rysunek 41. Predykcja krokowa na zbiorze testowym............................................................ 26 Rysunek 42. Funkcja sinusoidalna. .......................................................................................... 27 Rysunek 43. Predykcja na zbiorze uczącym. ........................................................................... 27 Rysunek 44. Predykcja krokowa na zbiorze testowym............................................................ 28 Rysunek 45. Predykcja ciągła na zbiorze testowym. ............................................................... 28 Rysunek 46. Predykcja na zbiorze uczącym. ........................................................................... 28 Rysunek 47. Predykcja krokowa na zbiorze testowym............................................................ 28 Rysunek 48. Predykcja ciągła na zbiorze testowym. ............................................................... 28 Rysunek 49. Funkcja sinusoidalno-malejąca. .......................................................................... 29 Rysunek 50. Predykcja na zbiorze uczącym. ........................................................................... 29 Rysunek 51. Predykcja krokowa na zbiorze testowym............................................................ 30 Rysunek 52. Predykcja ciągła na zbiorze testowym. ............................................................... 30 Rysunek 53. Predykcja na zbiorze uczącym. ........................................................................... 30 Rysunek 54. Predykcja krokowa na zbiorze testowym............................................................ 30 Rysunek 55. Predykcja ciągła na zbiorze testowym. ............................................................... 30 Rysunek 56. Predykcja na zbiorze uczącym. ........................................................................... 31 Rysunek 57. Predykcja krokowa na zbiorze testowym............................................................ 31 Rysunek 58. Predykcja na zbiorze uczącym. ........................................................................... 31 Rysunek 59. Predykcja krokowa na zbiorze testowym............................................................ 31 Rysunek 60. Funkcja notowań akcji firmy KGHM Polska Miedź S.A. .................................. 32 Rysunek 61. Predykcja na zbiorze uczącym. .......................Błąd! Nie zdefiniowano zakładki. Rysunek 62. Predykcja krokowa na zbiorze testowym............................................................ 33 Rysunek 63. Predykcja ciągła na zbiorze testowym. ............................................................... 33 Rysunek 64. Predykcja na zbiorze uczącym. ........................................................................... 33 Rysunek 65. Predykcja krokowa na zbiorze testowym............................................................ 34 Rysunek 66. Predykcja ciągła na zbiorze testowym. ............................................................... 34 Rysunek 67. Predykcja na zbiorze uczącym. .......................Błąd! Nie zdefiniowano zakładki. Rysunek 68. Predykcja krokowa na zbiorze testowym............................................................ 35 Rysunek 69. Predykcja ciągła na zbiorze testowym. ............................................................... 35 Rysunek 70. Predykcja na zbiorze uczącym. ........................................................................... 35 Rysunek 71. Predykcja krokowa na zbiorze testowym............................................................ 35 Rysunek 72. Predykcja na zbiorze uczącym. ........................................................................... 35 Rysunek 73. Predykcja krokowa na zbiorze testowym............................................................ 35  Predykcja danych w szeregach czasowych  5/42  Rysunek 74. Predykcja na zbiorze uczącym. ........................................................................... 35 Rysunek 75. Predykcja krokowa na zbiorze testowym, ciągły w stosunku do zbioru uczącego. .......................................................................................................................................... 37 Rysunek 76. Predykcja ciągła na zbiorze testowym, po okresie jednorocznej przerwy, w stosunku do zbioru uczącego............................................................................................ 37 Rysunek 77. Okno główne programu - widok parametrów nauki. .......................................... 38 Rysunek 78. Okno główne programu - widok parametrów predykcji ..................................... 39 Rysunek 79. Okno główne programu - widok danych wyników. ............................................ 39 Rysunek 80. Okno główne programu - widok danych predykcji............................................. 40  Predykcja danych w szeregach czasowych  6/42  1. Wstęp Dokument ten poświęcony jest zagadnieniu predykcji danych w szeregach czasowych. Na wstępie postaramy się wyjaśnić podstawowe pojęcia uŜywane zarówno w tytule jak i dalszej części niniejszej pracy. Jednym z kluczowych pojęć jest predykcja danych, polega ona na próbie przewidzenia t przyszłych wartości funkcji na podstawie n wcześniejszych wartości. Drugim bardzo waŜnym pojęciem jest szereg czasowy, który jest ciągiem następujących po sobie czasowo wartości. Szereg czasowy moŜe na przykład stanowić odczyt wskazań urządzenia pomiarowego lub zestawienie cen akcji giełdowych danej spółki na giełdzie. Predykcja cen akcji giełdowych jest niezmiernie interesująca dziedziną biorąc pod uwagę korzyści, jakie moŜe przynieść dokładne prognozowanie kolejnych wartości cenowych. Na podstawie tych prognoz moŜna podejmować decyzję czy dane akcje warto kupować w danej chwili czy teŜ moŜe lepiej je sprzedać. Im predykcja jest bardziej dokładna tym lepiej moŜna operować dysponowanymi przez nas pieniędzmi. Nic więc dziwnego, Ŝe prowadzi się wiele prac na ten temat. Niestety wiele z rozwiązań nie jest publikowanych i stanowią one jedynie część całych pakietów, których cena jest czasami niesamowicie wysoka. Predykcja moŜe być krótko lub długookresowa. Predykcja krótko okresowa dotyczy zazwyczaj predykcji kilku wartości w przód, podczas gdy predykcja długookresowa swoim zasięgiem moŜe obejmować bardzo długie okresy. Przyjmuje się, Ŝe dla predykcji krótko okresowych błąd szacowanych wartości z wartościami rzeczywistymi powinien być bardzo mały. Podczas predykcji długookresowej tolerowana jest nawet znaczna rozbieŜność na rzecz zachowania ogólnego trendu danych. W dokumencie tym opisane jest wykorzystanie sieci neuronowych oraz metod regresji w zadaniu predykcji danych. Metody te zostaną dokładnie scharakteryzowane w dalszej części tej pracy.  Predykcja danych w szeregach czasowych  7/42  2. Dane Udało się uzyskać dane giełdowe spółki KGHM z lat 2001 – 2005, pobrane one zostały z serwisu www.money.pl. Wśród wartości, jakimi dysponowaliśmy były: • • • • • • Cena otwarcia Cena minimalna w ciągu dnia Cena maksymalna w ciągu dnia Cena podczas zamknięcia giełdy Procentowa zmiana w stosunku do dnia poprzedniego Ilość sprzedanych akcji w ciągu dnia (wolumen)  W Tabela 1 znajduje się przykład formatu wykorzystywanych danych. Tabela 1. Dane giełdowe dla akcji spółki KGHM. Data 2005-05-27 2005-05-25 2005-05-24 2005-05-23 2005-05-20 2005-05-19 2005-05-18 2005-05-17 2005-05-16 Otw 29,10 28,60 28,60 28,70 28,90 28,90 28,30 28,90 29,00 Min 29,00 28,60 28,10 28,50 28,50 28,50 27,70 27,70 28,20 Max 29,40 29,00 28,70 29,00 29,40 29,00 28,50 28,90 29,00 Zamkn 29,40 28,90 28,60 28,60 28,60 29,00 28,40 28,10 28,60 Zmn.[%] Wolumen 1,73 1,05 0,00 0,00 -1,38 2,11 1,07 -1,75 -1,72 328848 271585 256392 231664 549326 1188384 818496 702573 207168  s Uznaliśmy, Ŝe interesująca z naszego punktu widzenia jest szczególnie wartość dotycząca ceny akcji podczas zamknięcia giełdy. Posiadane przez nas dane zostały poddane wstępnemu preprocessingowi, w którym usunęliśmy kolumny nie istotne z naszego punktu widzenia. W Tabela 2 został pokazany widok danych po tym procesie. Tabela 2. Dane po preprocessingu. Data 2005-05-27 2005-05-25 2005-05-24 2005-05-23 2005-05-20 2005-05-19 2005-05-18 2005-05-17 2005-05-16 Zamkn 29,40 28,90 28,60 28,60 28,60 29,00 28,40 29,40 28,90  Na Rysunek 1 przedstawiona jest zmiana wartości akcji w czasie.  Predykcja danych w szeregach czasowych Dane giełdowe spółki KGHM 45,00  8/42  40,00  35,00  30,00 Wartość akcji [zł]  25,00  20,00  15,00  10,00  5,00  0,00 2005-05-27 2005-04-18 2005-03-07 2005-01-27 2004-12-21 2004-11-12 2004-10-04 2004-08-26 2004-07-20 2004-06-11 2004-05-04 2004-03-23 2004-02-13 2004-01-07 2003-11-25 2003-10-16 2003-09-09 2003-07-31 2003-06-24 2003-05-15 2003-04-03 2003-02-25 2003-01-17 2002-12-05 2002-10-24 2002-09-17 2002-08-08 2002-07-01 2002-05-20 2002-04-09 2001-11-20 2001-07-30 2001-04-04 2000-08-11 1999-05-25 1999-03-29 1999-01-22 1998-11-09  Data [dni]  Rysunek 1. Dane giełdowe spółki KGHM.  PoniewaŜ nie widać w tych danych wyraźniej zaleŜności postanowiliśmy przebadać nasze rozwiązanie równieŜ na innych danych wejściowych. Wybraliśmy do tego następujące funkcje: • • • • Funkcja liniowa y = ax+b Funkcja kwadratowa y = ax2 + bx + c Funkcja okresowa y = sin(x) + a Funkcja okresowa y = sin(x) + x  PoniŜej znajdują się wykresy tych funkcji.  Predykcja danych w szeregach czasowych  Cena [zł] 10000 12000 14000  Cena [zł] 100 200 300 400 500 600 700 800 900 0  2000  4000  6000  8000  2003-01-27 2003-03-27 2003-05-27 2003-07-27  0 2002-04-16 2002-06-16 2002-08-16 2002-10-16 2002-12-16  Rysunek 3. Wykres funkcji kwadratowej.  Funkcja kwadratowa y=ax^2+bx+c  Rysunek 2. Wykres funkcji liniowej.  2003-02-16 2003-04-16 2003-06-16 2003-08-16 Data [dni] 2003-10-16 2003-12-16 2004-02-16 2004-04-16 2004-06-16 2004-08-16 2004-10-16 2004-12-16 2005-02-16  2003-09-27  Funkcja liniowa y=-ax+b  2003-11-27 2004-01-27 Data [dni] 2004-03-27 2004-05-27 2004-07-27  2004-09-27 2004-11-27 2005-01-27 2005-03-27  2005-04-16  2005-05-27  9/42  Predykcja danych w szeregach czasowych  Cena [zł] 10,00 12,00 14,00  Cena [zł] 10,5 11,5 8,5 9,5 10 11 8 9  0,00 2002-04-16 2002-06-16 2002-08-16 2002-10-16 2002-12-16  2,00  4,00  6,00  8,00  2002-04-16 2002-06-16 2002-08-16 2002-10-16 2002-12-16  Rysunek 5. Funkcja okresowa sin(x) + x  Rysunek 4. Funkcja okresowa sin(x) + a  2003-02-16 2003-04-16  2003-02-16 2003-04-16 2003-06-16 2003-08-16 Data [dni] 2003-10-16 2003-12-16 2004-02-16 2004-04-16 2004-06-16 2004-08-16 2004-10-16 2004-12-16 2005-02-16 2005-04-16  Funkcja okresowa y=sin(x)+a  Fukncja sin(x)+x  2003-06-16 2003-08-16 Data [dni] 2003-10-16 2003-12-16 2004-02-16 2004-04-16 2004-06-16 2004-08-16 2004-10-16 2004-12-16 2005-02-16 2005-04-16  10/42  Predykcja danych w szeregach czasowych  11/42  3. Predykcja Jak wspominaliśmy juŜ we wstępie predykcja ma za zadanie oszacowanie wartości funkcji na podstawie innych jej wartości. Predykcja w szeregach czasowych bazuje na wartościach z przeszłości w celu próby oszacowania wartości w kolejnych punktach czasu. Jakość predykcji mierzy się zazwyczaj jako średnie odchylenie wartości uzyskanych w poszczególnych punktach od wartości rzeczywistych (oczekiwanych). Weźmy pod uwagę przykładową funkcję przedstawioną na Rysunek 6, oraz pewne punkty kontrolne t0, t1 oraz t2. Funkcja rzeczywista, czyli ta która próbujemy oszacować narysowana jest linią ciągłą, zaś nasze oszacowanie na wykresie narysowane jest linią przerywaną. Z rysunku łatwo moŜna zobaczyć, Ŝe znalezione oszacowanie róŜni się od funkcji jakiej szukaliśmy.  Rysunek 6. Związek pomiędzy wartościami funkcji predykowanymi i rzeczywistymi.  Przyjęta przez nas miara jakości predykcji wyraŜona jest wzorem (1). Błąd predykcji: n  Err = Objaśnienie:  ∑o i =1  z  −o  (1)  n  Err – całkowity błąd predykcji o – wartość uzyskana z predykcji oz – wartość oczekiwana n – ilość elementów predykowanego zbioru  Predykcja danych w szeregach czasowych  12/42  Predykcja krótko okresowa – jest to rodzaj predykcji, który na podstawie wartości z przeszłości (okna) próbuje oszacować małą liczbę wartości w przyszłości. Podczas takiej predykcji nacisk kładziony jest na minimalizacje błędu predykcji. Podczas predykcji kaŜdej wartości wykorzystuje się dane rzeczywiste. W przypadku naszego programu byłaby to sytuacja, w której prognozuje on cenę akcji na następny dzień na podstawie wartości poprzednich. Za kaŜdym razem do programu podawane są rzeczywiste wartości cen akcji z dni poprzednich.  Cena [zł]  Rysunek 7. Idea predykcji krótko okresowej.  Predykcja długo okresowa – to rodzaj predykcji który ma na celu prognozę trendu badanej funkcji. Nacisk kładziony jest na zachowanie ogólnego charakteru funkcji, a niŜeli dokładne przewidzenie przyszłych wartości. Predykcja taka dokonywana jest zazwyczaj poprzez przesuwanie okna danych z jednoczesnym włączaniem do szeregu uczącego przewidzianych wartości. Schemat ideowy takiego rozwiązania przedstawiony jest na Rysunek 8.  Rysunek 8. Idea predykcji długo okresowej.  Predykcja danych w szeregach czasowych  13/42  4. Metody predykcji W programie zostały zastosowane trzy metody predykcji. Dwie z nich wykorzystują sztuczną sieć neuronową, trzecia natomiast opiera się na metodzie regresji wielomianowej dowolnego stopnia. Rozwiązanie hybrydowe umoŜliwia wykorzystanie dowolnej kombinacji tych metod. Na Rysunek 9 przedstawiony jest ideowy schemat pracy hybrydy z włączonymi wszystkimi metodami predykcji.  Rysunek 9. Schemat blokowy hybrydy.  W dalszej części tego rozdziału zostanie dokładnie wyjaśnione kaŜde z tych rozwiązań. Sieć neuronowa numeryczna Jako pierwsze omówimy rozwiązanie bazujące na sieci neuronowej z propagacją wsteczną. Nazwa „sieć numeryczna” została jej nadana ze względu na sposób pracy z danymi. Sieć ta składa się przynajmniej z trzech warstw (Rysunek 10), pierwsza warstwa – wejściowa, jest odpowiedzialna za pobieranie wartości funkcji. Liczność tej warstwy odpowiada dokładnie szerokości okna danych. KaŜdy neuron pobiera wobec tego jedną wartość z okna i przekazuje go do warstwy ukrytej. Warstwa ukryta jest konfigurowalna w programie. MoŜemy określić ile neuronów będzie wchodzić w jej skład. Dodatkowo mamy równieŜ moŜliwość określenia ilości tych warstw. W literaturze podawane jest jednak najczęściej, Ŝe sieć taka powinna posiadać jedną warstwę ukrytą o liczności równej ilości neuronów w warstwie wejściowej. W naszym programie postanowiliśmy jednak sprawdzić jak zachowują się sieci z większą ilością warstw ukrytych oraz z róŜna od wejściowej liczbą neuronów w nich zawartych. Warstwa wyjściowa składa się zawsze z jednego neuronu, którego wartość na wyjściu stanowi wynik działania sieci.  Predykcja danych w szeregach czasowych  14/42  Wyjście – denormalizacja wartości  Warstwa wyjściowa  Warstwa ukryta  1  2  3  4  5  6  7  8  Warstwa wejściowa  1  2  3  4  5  6  7  8  Wejścia do sieci – normalizacja danych  Rysunek 10. Schemat sieci numerycznej.  Błąd działania sieci: ilośl _ wyjsc ilosc _ wzorców  Blad = Objaśnienie:  ∑ (o i =0  Z  − o) 2  ∑ i =1  (2)  ilosc _ wyjsc  Blad –błąd pracy sieci neuronowej o – wartość uzyskana na wyjściu z neuronu warstwy wyjściowej oz – wartość oczekiwana na wyjściu neuronu ilosc_wzorców – ilość wzorców danych ilosc_wyjsc – ilość wyjść sieci neuronowej Wartości dostarczane do warstwy wejściowej poddaje się normalizacji zgodnie z następującym wzorem: Normalizacja wartości wejściowej  xs = Objaśnienie:  xr − min max − min  (3)  xs – wartość podawana na wejście sieci  Predykcja danych w szeregach czasowych xr – wartość rzeczywista przekazana na wejście min – minimalna wartość w zbiorze danych max – maksymalna wartość w zbiorze danych Wyjście z sieci następnie poddawane jest procesowi denormalizacji:  15/42  xs = xr ⋅ (max − min) + min Objaśnienie: xs – wartość podawana na wejście sieci xr – wartość rzeczywista przekazana na wejście min – minimalna wartość w zbiorze danych max – maksymalna wartość w zbiorze danych  (4)  Do uczenia sieci zastosowany jest algorytm propagacji wstecznej. KaŜdy z neuronów wchodzących w skład sieci ma dodatkowe wejście zwane biasem, które zawsze na wejściu ma podawaną wartość 1. Jako funkcja aktywacji neuronu zastosowana została funkcja unipolarna. Sieć neuronowa znakowa Sieć znakowa w naszym programie to specyficzny rodzaj sieci, która na wejściu analizuje nie wartości liczb a cyfry, z jakich one się składają. Efektem działania takiej sieci jest zatem predykcja pewnego napisu, który w szczególności będzie liczbą. Przykład konwersji liczby 2.5 na wejścia sieci znakowej został pokazany na Rysunek 11.  Rysunek 11. Schemat konwersji danych dla sieci znakowej.  NaleŜy zwrócić uwagę, Ŝe dla ciągu liczb 2.5; 2.51; 4.321 naleŜy ujednolicić ich zapis. W programie realizowane jest to dopisaniem tylu zer końcowych, aby długość kaŜdej liczby była taka sama. Dla naszego przykładu po takiej konwersji uzyskalibyśmy liczby (a w zasadzie napisy): 2.500 ; 2.510; 4.321  Predykcja danych w szeregach czasowych Budowa sieci znakowej jest następująca: • • •  16/42  Liczba neuronów w warstwie wejściowej – długość najdłuŜszej liczby (w postaci napisu) * 4 * szerokość okna Liczba neuronów w warstwie ukrytej – 0.5 * ilość neuronów wejściowych Liczba neuronów wyjściowych – długość najdłuŜszej liczby z danych uczących (w postaci napisu) * 4  Rysunek 12. Budowa sieci znakowej.  Liczba, 4 przez która przemnaŜana jest liczba neuronów warstwy wejściowej i wyjściowej, wynika z faktu konwersji kaŜdej cyfry na postać binarną. PoniewaŜ musimy zakodować 10 cyfr oraz przecinek, potrzebnych jest naw w tym celu 11 wartości, a najbliŜsza potęgą dwójki jest 4 (liczba 16). KaŜdy neuron sieci znakowej zbudowany jest tak samo jak neuron sieci numerycznej. Błąd sieci równieŜ liczony jest ze wzoru (2). Sieć uczona jest równieŜ algorytmem BackPropagation. Zdecydowaną róŜnicą, jaka cechuje sieć znakową i sieć liczbową poza sposobem interpretacji danych wejściowych jest ilość neuronów, jaka wchodzi w ich skład. Zastosowanie sieci znakowej wynikało z paru czynników. Pierwszy z nich polegał na chęci przetestowania zastosowalności i przydatności takiego podejścia. Nigdzie w literaturze nie spotkaliśmy się z podobnym rozwiązaniem, dlatego ciekawiło nas jakie rezultaty jesteśmy w stanie osiągnąć z jego pomocą. Drugim powodem jaki przemawiał za zastosowaniem sieci znakowej był fakt jej wraŜliwości nawet na bardzo małe zmiany wartości wejściowych. Wystarczy, Ŝe weźmiemy taki przykład: Zakres danych = 100 Wartość 1 = 45.500 Wartość 2 = 49.000 Wartość 3 = 45.506 Dla sieci numerycznej wartości 1 oraz 3 są w zasadzie nierozróŜnialne, podczas gdy w sieci znakowej zmianie ulegnie wartość 3 neuronów.  Regresja jest metodą, która polega na ustaleniu wzoru krzywej pewnego stopnia, w naszym przypadku jest to krzywa wielomianowa, poprzez dostrajanie jej parametrów. Dostrajanie to polega na minimalizacji średniego odchylenia krzywej aproksymującej prostą od funkcji bazowej. Wybranie stopnia wielomianu pozawala na mniejsze lub większe dopasowanie się krzywej regresji do funkcji. PoniŜej przedstawionych jest kilka przykładów, które demonstrują wpływ stopnia wielomianu na otrzymany wynik:  Regresja  Predykcja danych w szeregach czasowych  Wartość akcji [zł] Wartość akcji [zł]  10,00  15,00  20,00  25,00  30,00  35,00  40,00  45,00  0,00  5,00  10,00  15,00  20,00  25,00  30,00  35,00  40,00  45,00  0,00  5,00  2005-05-27  2005- 05-27  Rysunek 15. Przykład przybliŜenia funkcji wielomianem czwartego stopnia.  Rysunek 13. Przykład przybliŜenia funkcji wielomianem drugiego stopnia.  2005-04-19 2005-03-09 2005-02-01 2004-12-27 2004-11-19 2004-10-12 2004-09-06 2004-07-30 2004-06-24 2004-05-18 2004-04-07 2004-03-02  2005- 04-19 2005- 03-09 2005- 02-01 2004- 12-27 2004- 11-19 2004- 10-12 2004- 09-06 2004- 07-30 2004- 06-24 2004- 05-18 2004- 04-07 2004- 03-02  Rysunek 17.Przykład przybliŜenia funkcji wielomianem szóstego stopnia.  Dane giełdowe spółki KGHM  Dane giełdowe spółki KGHM  2004- 01-26 2003- 12-15 2003- 11-06 2003- 10-01 2003- 08-26 2003- 07-18 Data [dni] 2003- 06-11 2003- 05-06 2003- 03-26 2003- 02-18 2003- 01-13 2002- 12-02 2002- 10-22 2002- 09-16 2002- 08-08 2002- 07-02 2002- 05-22 2002- 04-12 2001- 12-14 2001- 08-22 2001- 05-16 2000- 10-13 1999- 08-25 1999- 04-26 1999- 02-15 1998- 12-02  2004-01-26 2003-12-15 2003-11-06 2003-10-01 2003-08-26 2003-07-18 Data [dni] 2003-06-11 2003-05-06 2003-03-26 2003-02-18 2003-01-13 2002-12-02 2002-10-22 2002-09-16 2002-08-08 2002-07-02 2002-05-22 2002-04-12 2001-12-14 2001-08-22 2001-05-16 2000-10-13 1999-08-25 1999-04-26 1999-02-15 1998-12-02  Wartość akcji [zł] 10,00 15,00 20,00 25,00 30,00 35,00 40,00 45,00 0,00 5,00  2005- 05-27 2005- 04-19 2005- 03-09 2005- 02-01 2004- 12-27 2004- 11-19 2004- 10-12 2004- 09-06 2004- 07-30 2004- 06-24 2004- 05-18 2004- 04-07 2004- 03-02  Dane giełdowe spółki KGHM  2004- 01-26 2003- 12-15 2003- 11-06 2003- 10-01 2003- 08-26 2003- 07-18 Data [dni] 2003- 06-11 2003- 05-06 2003- 03-26 2003- 02-18 2003- 01-13 2002- 12-02 2002- 10-22 2002- 09-16 2002- 08-08 2002- 07-02 2002- 05-22 2002- 04-12 2001- 12-14 2001- 08-22 2001- 05-16 2000- 10-13 1999- 08-25 1999- 04-26 1999- 02-15 1998- 12-02  Wartość akcji [zł] Wartość akcji [zł] 10,00 15,00 20,00 25,00 30,00 35,00 40,00 45,00 0,00 5,00 10,00 15,00 20,00 25,00 30,00 35,00 40,00 45,00 0,00 5,00 2005- 05-27  2005- 05-27  Rysunek 16. Przykład przybliŜenia funkcji wielomianem piątego stopnia.  Rysunek 14. Przykład przybliŜenia funkcji wielomianem trzeciego stopnia.  2005- 04-19 2005- 03-09 2005- 02-01 2004- 12-27 2004- 11-19 2004- 10-12 2004- 09-06 2004- 07-30 2004- 06-24 2004- 05-18 2004- 04-07 2004- 03-02  2005- 04-19 2005- 03-09 2005- 02-01 2004- 12-27 2004- 11-19 2004- 10-12 2004- 09-06 2004- 07-30 2004- 06-24 2004- 05-18 2004- 04-07 2004- 03-02  Dane giełdowe spółki KGHM  2004- 01-26 2003- 12-15 2003- 11-06 2003- 10-01 2003- 08-26 2003- 07-18 Data [dni] 2003- 06-11 2003- 05-06 2003- 03-26 2003- 02-18 2003- 01-13 2002- 12-02 2002- 10-22 2002- 09-16 2002- 08-08 2002- 07-02 2002- 05-22 2002- 04-12 2001- 12-14 2001- 08-22 2001- 05-16 2000- 10-13 1999- 08-25 1999- 04-26 1999- 02-15 1998- 12-02  Dane giełdowe spółki KGHM  2004- 01-26 2003- 12-15 2003- 11-06 2003- 10-01 2003- 08-26 2003- 07-18 Data [dni] 2003- 06-11 2003- 05-06 2003- 03-26 2003- 02-18 2003- 01-13 2002- 12-02 2002- 10-22 2002- 09-16 2002- 08-08 2002- 07-02 2002- 05-22 2002- 04-12 2001- 12-14 2001- 08-22 2001- 05-16 2000- 10-13 1999- 08-25 1999- 04-26 1999- 02-15 1998- 12-02  17/42  Predykcja danych w szeregach czasowych  18/42  5. Eksperymenty 1. Badanie błędu sieci podczas procesu uczenia Pierwsze badanie miało na celu określenie zaleŜności pomiędzy wartością błędu sieci, a długością procesu uczenia. Dla sieci numerycznej zaleŜność ta została przedstawiona na Rysunek 18, a dla sieci znakowej, na Rysunek 19. Jak widać obie zaleŜności mają charakter 1/x. Uczenie sieci numerycznej 3,5 3 2,5 Wartość błędu 2 1,5 1 0,5 0 1 51 101 151 201 251 301 351 Ilość epok uczących  Rysunek 18. Wykres zaleŜności błędu sieci numerycznej od ilości epok uczących. Błąd podczas uczenia sieci znakowej 5 4,5 4 3,5 Błąd sieci 3 2,5 2 1,5 1 0,5 0 1 26 51 Ilość epok 76  Rysunek 19. Wykres zaleŜności błędu sieci znakowej od ilości epok uczących.  Predykcja danych w szeregach czasowych  19/42  2. Badanie wpływu parametrów uczenia na ilość epok uczących oraz błąd sieci. Badanie polegało na sprawdzeniu wpływu parametrów uczenia takich jak: maksymalny dopuszczalny błąd, współczynnik uczenia. Jak widać (Tabela 3. Błąd predykcji sieci liczbowej dla zbioru uczącego.Tabela 3 i Tabela 4) zmniejszenie wartośći dopuszczalnego błędu wpływa na polepszenie jakości otrzymywanych rozwiązań. JednakŜe związane jest to z dodatkowym kosztem obliczeniowym, wynikającym z dłuŜszego procesu uczenia. Tabela 3. Błąd predykcji sieci liczbowej dla zbioru uczącego. L.p. 1 2 3 4 5 6 7 8 9 10 Średnia: Max_bład=0,1 Wsp_uczenia=0.25 0,33944595 0,40685362 0,3211001 0,39504743 0,30614528 0,3702581 0,55567235 0,4061748 0,44178638 0,34696692 0,388945093 Max_błąd=0,1 Wsp_uczenia=0.1 0,40188 0,377126 0,435145 0,399811 0,388575 0,401558 0,39477 0,39934 0,405562 0,399018 0,400279 Max_błąd=0,01 Wsp_uczenia=0.25 0,119438 0,087539 0,139914 0,178516 0,166054 0,100523 0,119242 0,393672 0,096405 0,212274 0,161358  Tabela 4. Liczba epok uczących sieci numerycznej dla zbioru testowego. L.p. 1 2 3 4 5 6 7 8 9 10 Średnia: Max_bład=0,1 Wsp_uczenia=0.25 128 51 54 32 61 31 47 73 36 38 50,11363636 Max_błąd=0,1 Wsp_uczenia=0.1 156 67 104 87 121 131 108 130 109 104 101,5545 Max_błąd=0,01 Wsp_uczenia=0.25 443 638 723 879 505 660 848 480 742 637 595,9318  Predykcja danych w szeregach czasowych 3. Predykcja funkcji  20/42  W celu porównania działania wykorzystanych metod, poddano predykcji następujące funkcje: • funkcja liniowa • funkcja kwadratowa • funkcja sinusoidalna (sin(x) + a) • funkcja sinusoidalna połączona z funkcja liniową (sin(x) + x) • funkcja przedstawiająca notowania cen akcji firmy KGHM Polska Miedź S.A. Proces testowania polegał na wyuczeniu sieci numerycznej i znakowej na wybranym podzbiorze dziedziny funkcji, a następnie próbie predykcji wartości dla nieznanych dotąd argumentów. W kolejnych punktach przedstawione są uzyskiwane rezultaty.  Predykcja danych w szeregach czasowych 4. Predykcja funkcji liniowej  21/42  Badania predykcji funkcji liniowej przedstawionej na Rys.20, miało na celu określenie zdolności systemu do wykrywania prostych zaleŜności między danymi.  Rysunek 20. Funkcja linowa.  Jako pierwszą zastosowaną metodę opartą na sieci numerycznej. Predykcję przeprowadzono dla dwóch wartości dopuszczalnego błędu: 1.0 i 0.01. Jak wynika z Rysunek 21 i Rysunek 24, obniŜenie progu błędu, pozwala na lepsze odwzorowanie funkcji, dla wartości wchodzących w skład zbioru uczącego. Wpływa to jednak ujemnie na zdolność uogólniania (Rysunek 22 i Rysunek 25). Akceptowalne rezultaty otrzymujemy jedynie dla predykcji krótkookresowej (krokowej). Dla predykcji długookresowej kumulacja błędu jest tak duŜa, Ŝe wartości predykowane nie zachowują nawet trendu funkcji bazowej (Rysunek 23 i Rysunek 26). Predykcja z zastosowaniem sieci numerycznej (max. błąd = 1):  Rysunek 21. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  22/42  Rysunek 22. Predykcja krokowa na zbiorze testowym.  Rysunek 23. Predykcja ciągła na zbiorze testowym.  Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.01):  Rysunek 24. Predykcja na zbiorze uczącym.  Rysunek 25 Predykcja krokowa na zbiorze testowym.  Rysunek 26 Predykcja ciągła na zbiorze testowym.  Predykcja danych w szeregach czasowych  23/42  Drugi test został przeprowadzony na sieci znakowej (zasada działania opisana w poprzednim punkcie). Uzyskane wyniki dla duŜego błędu (powyŜej 1) nie wykazują Ŝadnej (bardzo znikomą) korelacji z funkcją bazową (Rysunek 27 i Rysunek 28). Dopiero zmniejszenie dopuszczalnego błędu pozwoliło uzyskać akceptowalne wyniki dla zbioru uczącego. JednakŜe, tak jak podejrzewaliśmy, sieć ta ma tendencję do uczenia się na pamięć, co moŜna zaobserwować na Rysunek 29 i Rysunek 30. Predykcja z zastosowaniem sieci znakowej (max. błąd = 1):  Rysunek 27. Predykcja na zbiorze uczącym.  Rysunek 28. Predykcja krokowa na zbiorze testowym.  Predykcja z zastosowaniem sieci znakowej (max. błąd = 0.01)  Rysunek 29. Predykcja na zbiorze uczącym.  Rysunek 30. Predykcja krokowa na zbiorze testowym.  Predykcja danych w szeregach czasowych 5. Predykcja funkcji kwadratowej  24/42  Kolejny test przeprowadzony został dla funkcji kwadratowej, przedstawionej na Rysunek 31. Badanie to ma na celu sprawdzenie zdolności uogólniania zaleŜności funkcyjnej. Badania zostały przeprowadzone zarówno dla sieci numerycznej jak i sieci znakowej.  Rysunek 31. Funkcja kwadratowa.  Uzyskane wyniki są porównywalne z wynikami otrzymanymi w poprzednim badaniu. Po raz kolejny swoja przewagę wykazała sieć numeryczna. Podczas testów potwierdziło się poprzednie przypuszczenie, Ŝe dla małej dopuszczalnej wartości błędu sieci, uczy się ona na pamięć. PoniŜej znajdują się otrzymane wyniki. Predykcja z zastosowaniem sieci numerycznej (max. błąd = 1):  Rysunek 32. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  25/42  Rysunek 33. Predykcja krokowa na zbiorze testowym.  Rysunek 34. Predykcja ciągła na zbiorze testowym.  Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.01)  Rysunek 35. Predykcja na zbiorze uczącym.  Rysunek 36. Predykcja krokowa na zbiorze testowym.  Rysunek 37. Predykcja ciągła na zbiorze testowym.  Predykcja danych w szeregach czasowych  26/42  Predykcja z zastosowaniem sieci znakowej (max. błąd = 1)  Rysunek 38. Predykcja na zbiorze uczącym.  Rysunek 39. Predykcja krokowa na zbiorze testowym.  Predykcja z zastosowaniem sieci znakowej (max. błąd = 0.01)  Rysunek 40. Predykcja na zbiorze uczącym.  Rysunek 41. Predykcja krokowa na zbiorze testowym.  Predykcja danych w szeregach czasowych 6. Predykcja funkcji okresowej – y=sin(x) + a  27/42  Kolejne testy przeprowadzone zostały dla funkcji okresowej w celu zbadania zdolności sieci do uczenia się schematów. Na Rysunek 42 przestawiony jest wykres funkcji bazowej.  Rysunek 42. Funkcja sinusoidalna.  Podczas prowadzenia badań zaobserwowaliśmy, iŜ okresowość funkcji pozwala zmniejszyć dopuszczalny błąd. W poprzednich badaniach zabieg ten dał negatywne efekty, których przejawem była nauka wzorców na pamięć. W aktualnie testowanej funkcji cecha ta jest poŜądana. Predykcja z zastosowaniem sieci numerycznej (max. błąd = 1):  Rysunek 43. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  28/42  Rysunek 44. Predykcja krokowa na zbiorze testowym.  Rysunek 45. Predykcja ciągła na zbiorze testowym.  Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.01):  Rysunek 46. Predykcja na zbiorze uczącym.  Rysunek 47. Predykcja krokowa na zbiorze testowym.  Rysunek 48. Predykcja ciągła na zbiorze testowym.  Predykcja danych w szeregach czasowych 7. Predykcja funkcji okresowej – y=sin(x) + x  29/42  W celu zbadania zdolności uogólniania zaleŜności funkcyjnych przy jednoczesnym wykorzystaniu faktu okresowości funkcji, badaniu poddaliśmy funkcję y=sin(x)+x. Wykres funkcji znajduje się na Rysunek 49.  Rysunek 49. Funkcja sinusoidalno-malejąca.  Jak wykazują przeprowadzone badania sieć numeryczna z dobrym rezultatem potrafiła odwzorować trend rozpatrywanej funkcji. Wysoka dokładność predykcji została uzyskana nie tylko na wzorcach uczących, ale równieŜ na zbiorze testowym (Rysunek 54). Wyniki predykcji długookresowej (ciągłej) pozostają nadal niezadowalające (Rysunek 52 i Rysunek 55). Predykcja z zastosowaniem sieci numerycznej (max. błąd = 1):  Rysunek 50. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  30/42  Rysunek 51. Predykcja krokowa na zbiorze testowym.  Rysunek 52. Predykcja ciągła na zbiorze testowym.  Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.01):  Rysunek 53. Predykcja na zbiorze uczącym.  Rysunek 54. Predykcja krokowa na zbiorze testowym.  Rysunek 55. Predykcja ciągła na zbiorze testowym.  Predykcja danych w szeregach czasowych Predykcja z zastosowaniem sieci znakowej (max. błąd = 1):  31/42  Rysunek 56. Predykcja na zbiorze uczącym.  Rysunek 57. Predykcja krokowa na zbiorze testowym.  Predykcja z zastosowaniem sieci znakowej (max. błąd = 0.01):  Rysunek 58. Predykcja na zbiorze uczącym.  Rysunek 59. Predykcja krokowa na zbiorze testowym.  Predykcja danych w szeregach czasowych  32/42  8. Predykcja danych giełdowych na przykładzie notowań akcji firmy KGHM Polska Miedź S.A. Najbardziej istotnym testem z punktu widzenia projektu było badanie zaproponowanego rozwiązania na danych rzeczywistych. Wstępna analiza ciągu uczącego nie pozwalała nam zakładać, Ŝe istnieją w nim jakiekolwiek zaleŜności funkcyjne (Rysunek 60).  Rysunek 60. Funkcja notowań akcji firmy KGHM Polska Miedź S.A.  Predykcja z zastosowaniem sieci numerycznej (max. błąd = 1):  Rysunek 61. Predykcja na zbiorze uczącym  Predykcja danych w szeregach czasowych  33/42  Rysunek 62. Predykcja krokowa na zbiorze testowym.  Rysunek 63. Predykcja ciągła na zbiorze testowym.  Dla duŜej wartości dopuszczalnego błędu, sieć numeryczna nie odwzorowuje funkcji bazowej. Jest to związane z faktem bardzo małej róŜnicy pomiędzy kolejnymi wartościami w ciągu uczącym (Rysunek 61, Rysunek 62 i Rysunek 63). Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.01):  Rysunek 64. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  34/42  Rysunek 65. Predykcja krokowa na zbiorze testowym  Rysunek 66. Predykcja ciągła na zbiorze testowym.  Przy obniŜeniu wartości dopuszczalnego błędu, uzyskane rezultaty na ciągu testowym wykazują niesamowite zdolności predykcji danych. Sieć potrafiła poprawnie predykować wartości dla 4-miesięcznego okresu następującego po ciągu uczącym. Niemniej jednak zdolność do predykcji długoterminowej nie uległa znacznej poprawie. Okres predykcji w tym przypadku nie przekracza nawet tygodnia. Predykcja z zastosowaniem sieci numerycznej (max. błąd = 0.001):  Rysunek 67. Predykcja na zbiorze uczącym  Predykcja danych w szeregach czasowych  35/42  Rysunek 68. Predykcja krokowa na zbiorze testowym.  Rysunek 69. Predykcja ciągła na zbiorze testowym.  Predykcja z zastosowaniem sieci znakowej (max. błąd = 1):  Rysunek 70. Predykcja na zbiorze uczącym.  Rysunek 71. Predykcja krokowa na zbiorze testowym.  Predykcja z zastosowaniem sieci znakowej (max. błąd = 0.01)  Rysunek 72. Predykcja na zbiorze uczącym.  Rysunek 73. Predykcja krokowa na zbiorze testowym.  Predykcja danych w szeregach czasowych Predykcja z zastosowaniem sieci znakowej (max. błąd = 0.001)  36/42  Rysunek 74. Predykcja na zbiorze uczącym.  Rysunek 75. Predykcja krokowa na zbiorze testowym.  Zaskakującym jest fakt, iŜ sieć znakowa wykazuje zdolność do wiernego odwzorowywania tak złoŜonej funkcji. Wyniki uzyskane w tej części badań są dla nie duŜo lepsze, niŜ w poprzednich testach. W pewnych sytuacjach jest ona lepsza niŜ sieć numeryczna. Wytłumaczyć to moŜna faktem, iŜ w ciągu uczącym róŜnice pomiędzy kolejnymi elementami są bardzo małe. Predykcja z zastosowaniem sieci numerycznej i sieci znakowej (max. błąd = 0.01):  Rysunek 76. Predykcja na zbiorze uczącym.  Predykcja danych w szeregach czasowych  37/42  Rysunek 77. Predykcja krokowa na zbiorze testowym, ciągłym w stosunku do zbioru uczącego.  Rysunek 78. Predykcja ciągła na zbiorze testowym, po okresie jednorocznej przerwy, w stosunku do zbioru uczącego.  Ostatnie badanie polegało na sprawdzeniu jakości predykcji dla danych testowych, pochodzących z następujących po sobie lat. Jak moŜna zauwaŜyć dokładność działania sieci maleje wraz z  Predykcja danych w szeregach czasowych  38/42  6. Opis programu PoniŜsze rysunki przedstawiają interfejs programu oraz jego podstawowe funkcje. Okno z wykresem wyników Wybór metod predykcji Otrzymane krzywe predykcji Parametry sieci numerycznej Parametry regresji wielomianowej Parametry nauki sieci neuronowych Parametry zbiorów uczących Rozpoczęcie nauki  Rysunek 79. Okno główne programu - widok parametrów nauki.  Predykcja danych w szeregach czasowych  39/42  Parametry dotyczące zakresu predykcji Parametry dotyczące typu predykcji Rozpoczęcie predykcji  Uzyskane wartości z predykcji  Rysunek 80. Okno główne programu - widok parametrów predykcji  Dane kontrolne gromadzone w procesie nauki oraz predykcji  Rysunek 81. Okno główne programu - widok danych wyników.  Predykcja danych w szeregach czasowych  40/42  Wartość predykcji sieci znakowej  Wartość predykcji dla metody regresji  Wartość rzeczywista funkcji Wartość predykcji sieci numerycznej  Rysunek 82. Okno główne programu - widok danych predykcji.  Predykcja danych w szeregach czasowych  41/42  7. Wnioski Projekt dał nam moŜliwość zgłębienia wiedzy na temat predykcji i aproksymacji danych. Postawiony przed nami rzeczywisty problem, pozwolił nam zastosować własne rozwiązanie w postaci sieci znakowej. Podejście to nie było nigdzie opisane, dlatego z niecierpliwością oczekiwaliśmy na pierwsze wyniki. W celu zwiększenia efektywności tej metody, postanowiliśmy wspomóc ją innymi rozwiązaniami. Tworząc tym samym system hybrydowy. Nie ogranicza to w Ŝaden sposób naszych moŜliwości związanych z konfiguracją poszczególnych modułów. W celu oceny otrzymanego rozwiązania, przeprowadzone zostały testy na wybranych funkcjach o róŜnych charakterystykach. W dokumencie zamieszczone zostały wyniki przeprowadzonych badań. Sieć numeryczna w znakomitej większości przypadków wykazywała swoją przewagę nad innymi podejściami. Na jej korzyść przemawiają równieŜ: prostota oraz powszechnie znany algorytm uczenia. Zaproponowana przez nas sieć znakowa nie radziła sobie dobrze z funkcjami testowymi. Jednak dla funkcji rzeczywistej (notowań akcji na giełdzie) spisywała się ona porównywalnie lub w nielicznych przypadkach nawet lepiej niŜ sieć numeryczna. Efekt ten uzyskiwany był jednak tylko na krótkich przedziałach czasowych, nieznacznie oddalonych od zbioru uczącego. W projekcie uŜytkownik ma równieŜ moŜliwość wykorzystania metod statystycznych, jaką jest regresja wielomianowa. Rozwiązanie nasze cechuje bardzo dobra zdolność predykcji krótkookresowej, która moŜe być przydatna w rzeczywistych zastosowaniach, na przykład podczas gry na giełdzie. Wyniki predykcji długoterminowej są niezadowalające, czego moŜna się było spodziewać ze względu na kumulację błędów predykcji krótkookresowej, co w skali dłuŜszego okresu czasu odbiegało znacznie od wartości rzeczywistych. Projekt ten stanowił dla nas wyzwanie i pozwolił nam zgłębić nasza wiedzę w tej dziedzinie.  Predykcja danych w szeregach czasowych  42/42  Literatura Benjamin W. Wah, Minglun Qian „Constrained Formulations and Algorithms for Stock-Price Predictions Using Recurrent FIR Neural Networks” G. E. P. Box, G. M. Jenkins „Time Series Analysis: Forecasting and Control” Józef Kalisz, Ryszard Pełka, Ryszard Szplet „Problemy projektowe w precyzyjnej metrologii odcinków czasu” Rayid Ghani, Hillery Simmons „Predicting the End-Price of Online Auctions” Rick Martinelli „Market data prediction with adaptive kalman filter” Jeffrey K. MacKie-Mason Anna Osepayshvili Daniel M. Reeves Michael P. Wellman „Price Prediction Strategies for Market-Based Scheduling” Ivakhnenko, A.G. „Recent Developments of Self-Organising Modeling in Prediction and Analysis of Stock Market” Foster „Commodities Futures Price Prediction An Artificial Intelligence Approach” (presentation) Sven F. „Crone Bussiness Forecasting with Artificial Neural Networks” (presentation)   &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-279533919760164045?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/279533919760164045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=279533919760164045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/279533919760164045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/279533919760164045'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/03/predykcja-danych-w-szeregach-czasowych.html' title='Predykcja danych w szeregach czasowych'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1047272374594055609</id><published>2009-02-27T07:58:00.002+01:00</published><updated>2009-04-14T20:23:38.536+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>ADAPTACYJNY SYSTEM SYGNALIZACJI ŚWIETLNEJ    OPARTY NA ALGORYTMIE GENETYCZNYM</title><content type='html'>&lt;a title="View ADAPTACYJNY SYSTEM SYGNALIZACJI ŚWIETLNEJ OPARTY NA ALGORYTMIE GENETYCZNYM on Scribd" href="http://www.scribd.com/doc/14227085/ADAPTACYJNY-SYSTEM-SYGNALIZACJI-WIETLNEJ-OPARTY-NA-ALGORYTMIE-GENETYCZNYM" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;ADAPTACYJNY SYSTEM SYGNALIZACJI ŚWIETLNEJ OPARTY NA ALGORYTMIE GENETYCZNYM&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_922742608626433" name="doc_922742608626433" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=14227085&amp;access_key=key-2jk00rg98e0ucxrnydwn&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=14227085&amp;access_key=key-2jk00rg98e0ucxrnydwn&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_922742608626433_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/Research/Math-Engineering" style="text-decoration: underline;"&gt;Math &amp;amp; Engineering&lt;/a&gt;              &lt;a href="http://www.scribd.com/browse/Research/" style="text-decoration: underline;"&gt;Research&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/skrzy%C5%BCowanie" style="text-decoration: underline;"&gt;skrzyżowanie&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/metody%20symulacji%20ruchu" style="text-decoration: underline;"&gt;metody symulacji ruc&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1047272374594055609?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1047272374594055609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1047272374594055609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1047272374594055609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1047272374594055609'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/02/adaptacyjny-system-sygnalizacji.html' title='ADAPTACYJNY SYSTEM SYGNALIZACJI ŚWIETLNEJ    OPARTY NA ALGORYTMIE GENETYCZNYM'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3264954757232753337</id><published>2009-02-27T07:54:00.004+01:00</published><updated>2009-04-14T20:24:33.872+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Nowoczesne metody mikrosymulacji ruchu drogowego z      wykorzystaniem automatów komórkowych</title><content type='html'>&lt;a title="View Nowoczesne metody mikrosymulacji ruchu drogowego z wykorzystaniem automatów komórkowych on Scribd" href="http://www.scribd.com/doc/13968091/Nowoczesne-metody-mikrosymulacji-ruchu-drogowego-z-wykorzystaniem-automatow-komorkowych" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Nowoczesne metody mikrosymulacji ruchu drogowego z wykorzystaniem automatów komórkowych&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_709282570959307" name="doc_709282570959307" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13968091&amp;access_key=key-2a94jwv5iqbap2gzan3w&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13968091&amp;access_key=key-2a94jwv5iqbap2gzan3w&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_709282570959307_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/Research/Math-Engineering" style="text-decoration: underline;"&gt;Math &amp;amp; Engineering&lt;/a&gt;              &lt;a href="http://www.scribd.com/browse/Research/" style="text-decoration: underline;"&gt;Research&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/simulation" style="text-decoration: underline;"&gt;simulation&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/cellular" style="text-decoration: underline;"&gt;cellular&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3264954757232753337?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3264954757232753337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3264954757232753337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3264954757232753337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3264954757232753337'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/02/nowoczesne-metody-mikrosymulacji-ruchu.html' title='Nowoczesne metody mikrosymulacji ruchu drogowego z      wykorzystaniem automatów komórkowych'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-923243031101825831</id><published>2009-02-27T06:05:00.004+01:00</published><updated>2009-02-27T06:10:17.696+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Metody predykcji w szeregach czasowych</title><content type='html'>&lt;p&gt;&lt;br /&gt;"Metody predykcji w szeregach czasowych, na przykładzie predykcji cen akcji giełdowych spółki KGHM Polska Miedz S. A." referat wygłoszony na Konferencji Naukowej Studentów w 2006 roku.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;    Artykuł przedstawia wykorzystanie rozwiązania bazującego na sieciach neuronowych podczas predykcji danych w szeregach czasowych na przykładzie zarówno predykcji krótko jak i długo okresowej cen akcji spółki KGHM Polska Miedź S.A. Dokument szczegółowo omawia dwie architektury sieci neuronowych, jedna bazująca na znakowej reprezentacji, druga na wartościach rzeczywistych. Omówione zostały otrzymane wyniki oraz moŜliwości ulepszenia za pomocą rozwiązania hybrydowego wykorzystującego wyniki działania obu sieci połączone z analizą statystyczną.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.deltasoftware.pl/dokumenty/KupczykStanekKNS2006.pdf"&gt;Dokument PDF - Metody predykcji w szeregach czasowych, na przykładzie predykcji cen akcji giełdowych spółki KGHM Polska Miedz S. A. (167 kB)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-923243031101825831?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/923243031101825831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=923243031101825831' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/923243031101825831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/923243031101825831'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/02/metody-predykcji-w-szeregach-czasowych.html' title='Metody predykcji w szeregach czasowych'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3353484041434359926</id><published>2009-02-18T17:47:00.006+01:00</published><updated>2009-04-03T12:07:34.343+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Sztuczna Inteligencja - Systemy Hybrydowe</title><content type='html'>&lt;p&gt;&lt;br /&gt;Praca ta stanowi wprowadzenie w zagadnienie systemów hybrydowych (inteligentnych systemów hybrydowych). W dokumencie zawarte są podstawowe informacje dotyczące wyjaśnienia pojęć, przeglądu najczęściej wykorzystywanych metod sztucznej inteligencji oraz charakterystyki ich zalet i wad. Druga część pracy skupia się już na bardziej szczegółowych aspektach zagadnienia. Wyjaśnione w niej zostały powody oraz cele stosowania systemów hybrydowych, proponowane w literaturze architektury oraz modele komunikacji. Końcową część pracy stanowi analiza kierunków rozwoju.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Systemy_Hybrydowe_prezentacja.pdf"&gt;Systemy Hybrydowe - Prezentacja (965 kB)&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a title="View Michal Stanek-Systemy Hybrydowe on Scribd" href="http://www.scribd.com/doc/13570154/Michal-StanekSystemy-Hybrydowe" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Michal Stanek-Systemy Hybrydowe&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_962809606036709" name="doc_962809606036709" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="450" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13570154&amp;access_key=key-1f6cv2ont7umbifczgw1&amp;page=1&amp;version=1&amp;viewMode=list"&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;            &lt;param name="mode" value="list"&gt;       &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13570154&amp;access_key=key-1f6cv2ont7umbifczgw1&amp;page=1&amp;version=1&amp;viewMode=list" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_962809606036709_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle" mode="list" height="500" width="450"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/School-Work/Homework" style="text-decoration: underline;"&gt;Homework&lt;/a&gt;              &lt;a href="http://www.scribd.com/browse/School-Work/" style="text-decoration: underline;"&gt;School Work&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/systemy%20hybrydowe" style="text-decoration: underline;"&gt;systemy hybrydowe&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/sztuczna%20inteligencja" style="text-decoration: underline;"&gt;sztuczna inteligencj&lt;/a&gt;       &lt;/div&gt;  &lt;div style="display:none"&gt; &lt;br /&gt;Systemy Hybrydowe Wprowadzenie Michał Stanek (mikol@e-informatyka.pl) 21 stycznia 2005 Streszczenie Praca ta stanowi wprowadzenie w zagadnienie systemów hybrydowych (inteligentnych systemów hybrydowych). W dokumencie zawarte są podstawowe informacje dotyczące wyjaśnienia pojęć, przeglądu najczęściej wykorzystywanych metod sztucznej inteligencji oraz charakterystyki ich zalet i wad. Druga część pracy skupia się już na bardziej szczegółowych aspektach zagadnienia. Wyjaśnione w niej zostały powody oraz cele stosowania systemów hybrydowych, proponowane w literaturze architektury oraz modele komunikacji. Końcową część pracy stanowi analiza kierunków rozwoju.  1  SPIS TREŚCI  2  Spis treści 1 Wstęp 2 Metody sztucznej inteligencji 2.1 Krótki rys historyczny . . . . . . . . . . . . . 2.2 Przegląd metod sztucznej inteligencji . . . . . 2.2.1 Systemy eskpertowe . . . . . . . . . . 2.2.2 Sieci neuronowe . . . . . . . . . . . . . 2.2.3 Algorytmy genetyczne . . . . . . . . . 2.2.4 Logika rozmyta . . . . . . . . . . . . . 2.3 Ocena użyteczności poszczególnych rozwiązań 3 Systemy hybrydowe 3.1 Cele systemu hybrydowego . . . . . . . . . . 3.2 Architektury budowy systemów hybrydowych 3.2.1 Systemy niezależne . . . . . . . . . . . 3.2.2 Systemy transformujące . . . . . . . . 3.2.3 Systemy luźno związane . . . . . . . . 3.2.4 Systemy zintegorwane . . . . . . . . . 3.2.5 Systemy w pełni zintegrowane . . . . . 3.3 Modele pracy systemu hybrydowego . . . . . 3.4 Przykładowy system hybrydowy . . . . . . . 3.5 Kierunki rozwoju systemów hybrydowych . . 4 5 5 6 6 7 8 10 10 12 12 14 14 14 15 15 15 16 17 18  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  . . . . . . . . . .  Spis rysunków 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Kroki milowe rozwoju sztucznej inteligencji . . . . . . . . . . . . Reprezentacja ideowa systemu ekspertowego . . . . . . . . . . . . Model neuronu oraz sieci neuronowej . . . . . . . . . . . . . . . . Przykład klasteryzacji danych . . . . . . . . . . . . . . . . . . . . Schemat procesu działania algorytmu genetycznego . . . . . . . . Przykładowa reprezentacja zbiorów za pomocą logiki rozmytej . . Właściwości różnych metod sztucznej inteligencji . . . . . . . . . Możliwe elementy systemu hybrydowego . . . . . . . . . . . . . . Model systemu niezależnego . . . . . . . . . . . . . . . . . . . . . Model systemu transformującego . . . . . . . . . . . . . . . . . . Model systemu luźno powiązanego . . . . . . . . . . . . . . . . . Model systemu zintegrowanego . . . . . . . . . . . . . . . . . . . Model systemu w pełni zintegrowanego . . . . . . . . . . . . . . . Model przetwarzania w systemach hybrydowych . . . . . . . . . . Model ideowy połączenia Systemu ekspertowego z siecią neuronową Ilość prac naukowych na temat systemów hybrydowych . . . . . 5 6 8 8 9 10 11 13 14 14 15 16 16 17 18 19  SPIS RYSUNKÓW  3  17  Model agenta w systemie wieloagentowym . . . . . . . . . . . . .  19  1 WSTĘP  4  1  Wstęp  Wydaje mi się, że wprowadzenie do systemów hybrydowych powinienem rozpocząć od wyjaśnienia samej nazwy, ponieważ dla osób niezaznajomionych z zagadnieniem, może wydawać się dziwna i niezrozumiała, a przez to mylnie interpretowana. Według jednej z deﬁnicji słownikowych system jest układem elementów o określonej strukturze, będący uporządkowaną logicznie całością. Hybryda, to natomiast mieszaniec powstały ze skrzyżowania dwóch różnych gatunków, ras, odmian, dziwoląg łączący cechy różnych osobników. Idea systemu hybrydowego bazuje wobec tego na integracji wielu dostępnych technik, metod, narzędzi w jednej spójnej i określonej strukturze stanowiącej logicznie uporządkowaną całość (wspólnie dążącą do osiągnięcia celu). Nasuwa się wobec tego pytanie, po co łączy się wiele różnych rozwiązań? Najogólniej można powiedzieć, że w celu osiągnięcia bardziej zadawalającego efektu niż przy wykorzystaniu każdej z tych technik osobno. Inteligentne systemy hybrydowe (Intelligent Hybrid Systems) starają się integrować odmienne techniki sztucznej inteligencji (logika rozmyta, sieci neuronowe, obliczenia ewolucyjne, metody probabilistyczne, maszynowe uczenie, systemy ekspertowe, itd. . . ). Fundamentem powstawania takich rozwiązań jest stwierdzenie, że metody te między sobą są komplementarne. W praktyce oznacza to, że metody te wzajemnie się uzupełniają, wady jednej są kompensowane zaletami innej. Istnieje wiele możliwych kombinacji wśród systemów symbolicznych i metod tak zwanej miękkiej sztucznej inteligencji (soft-computing) 1 , oraz wiele możliwych sposobów ich łączenia. Dla przykładu sieci neuronowe mogą być łączone z logiką rozmytą, wnioskowaniem na podstawie przykładów, algorytmami genetycznymi. W ostatnich latach, bardzo gwałtowny wzrost zapotrzebowania na wyraﬁnowane i złożone rozwiązania z dziedziny inteligentnych systemów informatycznych sprawia, że osiągnięcie pełnego sukcesu nie jest możliwe bez wykorzystania możliwości, jakie oferują nam systemy hybrydowe. Reprezentacja i manipulacja, przy pomocy komputerów, dużymi ilościami wiedzy oraz zapewnienie ich integralności, spójności i efektywności wykorzystania jest jednym z kluczowych nurtów badań w dziedzinie szeroko pojętej sztucznej inteligencji. Należy zdawać sobie sprawę z tego, że przyjęty przez nas format przechowywania i reprezentacji wiedzy powinien być w stanie poradzić sobie z pewnymi oczywistymi problemami. Niedokładność i niekompletność zgromadzonej wiedzy to jeden z nich. Różne sposoby przechowywania tejże wiedzy (np. sieci neuronowe, logika rozmyta, systemy ekspertowe) posiadają specyﬁczne własności radzenia sobie z danymi niepewnymi, nieprecyzyjnymi albo nawet nieprawidłowymi. Pewne metody lepiej nadają się do przechowywania danych numerycznych, jeszcze inne sprawdzają się lepiej, kiedy pragniemy operować na danych w postaci symbolicznej. Nie ma zadowalającego uniwersalnego rozwiązania, pozwalającego radzić sobie z wszystkimi problemami związanymi z reprezentacją wiedzy. 1 Pierwszy  raz użył tego terminu Lotﬁ A. Zadeh 1995  2 METODY SZTUCZNEJ INTELIGENCJI  5  2 2.1  Metody sztucznej inteligencji Krótki rys historyczny  Podobnie jak wiele innych, sztuczna inteligencja jest dziedziną nauki, która rozwija się w bardzo prężny sposób. W stosunkowo krótkiej historii, bo zaledwie 60 letniej, zaproponowano wiele koncepcji, które w znaczącym stopniu przyczyniły się do rozwoju, nie tylko jej, ale również wielu innych dziedzin w tym np. teorii sterowania i podejmowania decyzji. Pewne kroki milowe rozwoju AI (Artiﬁcial Intelligence) prezentuje rysunek 1. Wiele proponowanych teorii inspirowanych było przez naturę. Podczas gdy jedne próbowały ją naśladować (systemy ekspertowe, wnioskowanie na podstawie przykładów, logika rozmyta) inne ją kopiowały (sieci neuronowe, algorytmy genetyczne). Bardzo dużo danych wdrożeń systemów sztucznej inteligencji, projektowanych jako systemy ekspertowe, miało miejsce na przełomie lat 1970 1980 (MYCIN, DENDRAL, PROSPECTOR). Systemy te zostały tak oto zdeﬁniowane przez prof. Feigenbaum’a: ”inteligentne programy komputerowe wykorzystujące wiedzę oraz mechanizm wnioskowania w celu rozwiązania problemów, które są na tyle skomplikowane, że celem ich rozwiązania wymagają szczegółowej ekspertyzy wykonanej przez człowieka”. Każde z rozwiązań posiadało jednak pewne braki i ograniczenia. Problemem systemów ekspertowych była między innymi akwizycja wiedzy. Nowe rozwiązania, były odpowiedzią na wady poprzednich. Nowe koncepcje wprowadzały nowe możliwości, ale jednocześnie nowe ograniczenia. W pewnym momencie stało się oczywiste, że pewne metody da się, a nawet trzeba ze sobą łączyć, aby móc z ich pomocą rozwiązać problemy, które wcześniej były nierozwiązywalne (przy wykorzystaniu tylko jednej). W ten sposób postało pojęcie i rozpoczęły się badania nad systemami hybrydowymi.  Rysunek 1: Kroki milowe rozwoju sztucznej inteligencji  2 METODY SZTUCZNEJ INTELIGENCJI  6  2.2 2.2.1  Przegląd metod sztucznej inteligencji Systemy eskpertowe  Tak jak zostało to przedstawione w poprzednim punkcie idea systemu ekspertowego zainspirowana była sposobem, w jaki ludzie (eksperci w danej dziedzinie) rozwiązują zagadnienia i na podstawie pewnych przesłanek dochodzą do konkluzji (wniosków). Typowa budowa systemu ekspertowego została przedstawiona na rysunku 2. Poszczególne bloki odpowiadają za inne funkcje, bloki przedstawione kolorem jasnoszarym prezentują właściwą część systemu ekspertowego: • Baza wiedzy - stanowi bazę faktów, jaką dysponuje system. Baza ta budowana jest na podstawie danych pozyskanych od ekspertów dziedzinowych, a przekazuje ją do systemu inżynier wiedzy. • Blok rozumowania (mechanizm wnioskowania) jest to najważniejszy składnik systemu ekspertowego, jego zadaniem jest wyciąganie wniosków z przesłanek i pytań wprowadzanych przez użytkownika i generowanie odpowiedzi. • Mechanizmu wyjaśniający - umożliwia wyjaśnienie, na życzenie użytkownika, dlaczego system udzielił takiej, a nie innej odpowiedzi, albo dlaczego system zadał użytkownikowi określone pytanie. Ekstrakcją wiedzy od ekspertów zajmują się na ogół inżynierowie wiedzy. Jest to zwykle długi i żmudny proces, ponieważ wiedza stosowana przez ludzkich ekspertów jest zwykle wiedzą praktyczną i intuicyjną.  Rysunek 2: Reprezentacja ideowa systemu ekspertowego  2 METODY SZTUCZNEJ INTELIGENCJI  7  Początkowo systemy ekspertowe były podatne na problemy związane z akwizycją (pozyskiwaniem wiedzy) i wnioskowaniem z niepewnością. W gruncie rzeczy problem transferu wiedzy ludzkiej do systemu ekspertowego jest kluczowy i nazywany jest w literaturze ”‘wąskim gardłem akwizycji wiedzy”’ (knowledge acquisition bottleneck ) [Giarratano98]. Jest to oczywiste o ile zrozumie się jak ciężkim i długim procesem jest przekazanie posiadanej przez eksperta wiedzy. Często wiedza ta jest rutynowa, bądź też intuicyjna, a sam ekspert nie zdaje sobie sprawy z jej posiadania. Drugim problemem systemów ekspertowych jest przekazywanie wiedzy nieścisłej, niepełnej i przybliżonej. Systemy ekspertowe wykorzystywane są m.in. w zagadnieniach: • diagnozowania, • przewidywania, • interpretacji, • planowania, • kontroli. 2.2.2 Sieci neuronowe  Idea sieci neuronowych zainspirowana została modelem funkcjonowania mózgu człowieka. Sieć neuronowa składa się z neuronów oraz połączeń miedzyneronowych (rysunek 3). Sieć uczy się zależności, które występują między danymi, można powiedzieć, że sama ekstrahuje reguły, które w systemie ekspertowym trzeba było przekazać ręcznie. Informacje na temat tych właśnie reguł kodowane są w połączeniach miedzyneuronowych, a dokładniej w wagach wejść każdego neuronu. W odróżnieniu od systemu ekspertowego, typowa sieć neuronowa pracuje na danych numerycznych, a nie symbolicznych. Problemem staje się proces wyjaśnienia, dlaczego sieć odpowiedziała tak a nie inaczej. Wiedza nie jest zapisana w czytelny dla człowieka sposób. Można powiedzieć, że sieć działa i generuje odpowiedzi, ale tak naprawdę nie wiemy, dlaczego takie a nie inne. Jest to bardzo poważne ograniczenie, ponieważ czasami musimy wiedzieć, na jakiej podstawie została podjęta pewna decyzja. Dużą zaletą sieci neuronowych jest fakt automatycznego wydobywania wiedzy z przykładów uczących (tutaj pojawia się problem doboru odpowiednich przykładów uczących i testujących). Oprócz sieci neuronowych uczonych z nauczycielem istnieją również sieci, które uczą się bez nadzoru (rysunek 3). Wynikiem ich nauki jest rozpoznanie zależności, jakie występują miedzy danymi. Sieci takie potraﬁą wyróżniać klastry danych (grupy danych pod jakimś względem do siebie podobnych). Sieci neuronowe wykorzystywane są m.in. do: • rozpoznawania obiektów, • kompresji danych,  2 METODY SZTUCZNEJ INTELIGENCJI  8  • analizy serii danych i przewidywania, • detekcji anormalnych stanów pracy systemu, • analizy oraz klasteryzacji danych, • wizualizacji danych - wielowymiarowych zbiorów danych.  Rysunek 3: Model neuronu oraz sieci neuronowej  Rysunek 4: Przykład klasteryzacji danych  2.2.3  Algorytmy genetyczne  Algorytmy genetyczne zainspirowane zostały obserwacją procesu ewolucji żywych organizmów. Koncepcja ta przeniesiona została przez Johna H. Holland’a  2 METODY SZTUCZNEJ INTELIGENCJI  9  w świat komputerów. Wystarczy założyć, że pewnym środowiskiem jest dziedzina problemu, jaki chcemy rozwiązać. Kodujemy teraz potencjalne początkowe rozwiązania jako osobniki naszej populacji. Następnie uruchamiamy proces ewolucji, w którym osobniki słabiej przystosowane eliminujemy (proces selekcji), a osobniki lepsze poddajemy procesowi krzyżowania. Skrzyżowany osobnik posiada część informacji przekazanej przez swoich rodziców (potencjalnie dobre rozwiązania). Z czasem osobniki będą coraz lepiej przystosowane do danego środowiska, czyli w naszym przypadku będą to coraz lepsze rozwiązania z przestrzeni zadania. Najczęściej działanie algorytmu przebiega następująco: 1. Losowana jest pewna populacja początkowa. 2. Populacja poddawana jest ocenie (selekcja). Najlepiej przystosowane osobniki biorą udział w procesie reprodukcji. 3. Genotypy najlepszych osobników są ze sobą kojarzone poprzez złączanie genotypów rodziców (krzyżowanie). 4. Przeprowadzana jest mutacja, czyli wprowadzenie drobnych losowych zmian. 5. Rodzi się drugie pokolenie i algorytm powraca do kroku drugiego, jeżeli nie znaleziono dostatecznie dobrego rozwiązania. W przeciwnym wypadku uzyskujemy wynik.  Rysunek 5: Schemat procesu działania algorytmu genetycznego Algorytmy genetyczne stosowane są m.in. do: • harmonogramowania,  2 METODY SZTUCZNEJ INTELIGENCJI  10  • optymalizacji ułożenia elementów w układach cyfrowych, • znajdowanie optymalnych wartości parametrów, • optymalizacja długości drogi. 2.2.4 Logika rozmyta  Logika rozmyta (fuzzy logic)2 , jedna z logik wielowartościowych (multi-valued logic), stanowi uogólnienie klasycznej dwuwartościowej logiki. Została zaproponowana przez Lotﬁ Zadeha w 1965 roku. W logice rozmytej między stanem 0 (fałsz) a stanem 1 (prawda) rozciąga się szereg wartości pośrednich (rysunek 6), które można kojarzyć z prawdopodobieństwem. Logika rozmyta okazała się bardzo przydatna w zastosowaniach inżynierskich, czyli tam, gdzie klasyczna logika klasyﬁkująca jedynie według kryterium prawda/fałsz nie potraﬁ skutecznie poradzić sobie z wieloma niejednoznacznościami i sprzecznościami. Logika rozmyta wykorzystywana jest m.in. w: • elektronicznych systemach sterowania (maszynami, pojazdami i automatami), • zadaniach eksploracji danych, • budowie systemów ekspertowych  Rysunek 6: Przykładowa reprezentacja zbiorów za pomocą logiki rozmytej  2.3  Ocena użyteczności poszczególnych rozwiązań  W poprzednim podpunkcie zostało przedstawione kilka najważniejszych metod sztucznej inteligencji. Został przedstawiony ich sposób działania oraz przykładowe zastosowania. Zwrócona została również uwaga na pewne mocne i słabe strony każdego z rozwiązań. 2 Deﬁnicja  zaczerpnięta z Wikipedii, wolnej encyklopedii internetowej.  2 METODY SZTUCZNEJ INTELIGENCJI  11  Przyjrzyjmy się najważniejszym ograniczenią każdej z prezentowanych wcześniej metod: • Sieci neuronowe - brak wyjaśnień • Sieci samoorganizujące - brak możliwości rozwiązywania zadań • Systemy ekspertowe - nie są wystarczająco elastyczne • Algorytmy genetyczne - czasami nie da się zastosować, ze względu na kłopot z kodowaniem osobników, specyﬁczną dziedzinę problemu lub też inne specyﬁczne czynniki. • Systemy rozmyte - są rozmyte. . . Właściwości poszczególnych rozwiązań zostały przedstawione na rysunku 7. Oś pionowa demonstruje zdolność adaptacji metody do zmieniających się warunków pracy (w stosunku do założonych warunków początkowych), oś pozioma demonstruje przejście pomiędzy poziomem operacji na liczbach do operacji na wiedzy formalnej.  Rysunek 7: Właściwości różnych metod sztucznej inteligencji  3 SYSTEMY HYBRYDOWE  12  3 3.1  Systemy hybrydowe Cele systemu hybrydowego  Projektując inteligentny system informatyczny musimy zadać sobie pytanie, jaki jest cel jego pracy oraz na jakim rodzaju danych system będzie on pracował. Wcześniej wspomniany był problem akwizycji wiedzy w kontekście jej niepewności, sprzeczności itp. Przyjrzyjmy się jednak, z jakim rodzajami wiedzy mamy my, na co dzień do czynienia: • Film rozpocznie się o 8:15. [Dokładna] • Film rozpocznie się między 8:00 a 9:00. [Nieprecyzyjna] • Sądzę, że ﬁlm rozpocznie się o 8:00, ale nie jestem pewien. [Niepewna] • Film rozpocznie się około 8:00. [Przybliżona] • Możliwe, że ﬁlm rozpocznie się o 8:00. [Możliwa] • Prawdopodobnie ﬁlm rozpocznie się o 8:00 (90 %). [Prawdopodobna] • Marek mówi, że ﬁlm rozpocznie się o 8:00, ale Kasia mówi, że o 9:00. [Niespójna] • Nie wiem dokładnie, o której rozpocznie się ﬁlm, ale zazwyczaj zaczyna się o 9:00. [Niekompletna] • Naprawdę nie wiem, o której zaczyna się ﬁlm. [Nieznana] • Jestem pewien, że ﬁlm nie zaczyna się z rana. [Negacja] • Film zaczyna się 2 godziny, po poprzedniej sesji. [Względna] • Film jest grany dzisiaj o 8:00 oraz jutro o 10:00. [Alternatywna] • Film zaczyna się o 8:00, 10:00 oraz 12:00. [Opcjonalna] • Film może się rozpocząć tylko pod warunkiem, że reżyser przyjedzie. [Asocjacyjna] • W następnym miesiącu. [Temporalna] Wiedza ludzka jest często trudna do wyrażenia w formacie, na jakim zazwyczaj operują komputery. Typowym jest fakt, że nie potraﬁmy sformułować naszej wiedzy w specyﬁcznym języku (formie) jej reprezentacji. Ludzie rozwiązują problemy oraz operują na posiadanej wiedzy za pomocą następujących mechanizmów: • wnioskowanie, • analogia,  3 SYSTEMY HYBRYDOWE  13  • dedukcja, • bazowanie na wcześniejszych doświadczeniach. Naturalna inteligencja bazuje na wielu ”hybrydowych” sposobach jej reprezentacji i manipulacji. Podobnie celem stosowania systemów hybrydowych w dziedzinie sztucznej inteligencji jest: • wykorzystanie całej dostępnej wiedzy na temat specyﬁcznego problemu, • możliwości skorzystania z wielu typów informacji (symbolicznej, numerycznej, nieścisłej, nieprecyzyjnej), • zaoferowanie wielu różnych schematów rozumowania i bardziej trafnego wyszukiwania odpowiedzi na zadawane pytania, • zwiększenia ogólnej efektywności systemu i eliminacja ujemnych stron pojedynczych metod, • stworzenie wydajnych i potężnych systemów rozumowania. Aby osiągnąć te cele konstruuje się systemy hybrydowe w skład, których mogą wchodzić metody przedstawione na rysunku 8  Rysunek 8: Możliwe elementy systemu hybrydowego  3 SYSTEMY HYBRYDOWE  14  3.2  Architektury budowy systemów hybrydowych  Architektury systemów hybrydowych mogą być sklasyﬁkowane według stopnia integracji i sposobu integracji. Stopień integracji jest kryterium do mierzenia stopnia integracji pomiędzy dwoma modułami systemu hybrydowego. 3.2.1 Systemy niezależne  Niezależne systemy hybrydowe charakteryzują się tym, że pomiędzy poszczególnymi modułami systemu nie istnieje żadna komunikacja (rysunek 9). Każdy moduł, nie korzysta w żaden sposób z wyników pracy innego modułu. Podejścia tego typu ma tą dobrą zaletę, że daje się zrównoleglić w bardzo dużym stopniu. Niezależność dwóch pracujących systemów może służyć również badaniu efektywności obu rozwiązań. Model ten może być również przyjęty w przypadku prototypowania systemu.  Rysunek 9: Model systemu niezależnego  3.2.2  Systemy transformujące  System hybrydowy bazujący na modelu transformującym działa na takiej zasadzie, że wyniki pracy jednego modułu systemu są transformowane do innego modułu (np. jako dane wejściowe). Rozwiązanie takie nadaje się bardzo dobrze w przypadkach, kiedy przed przekazaniem danych do głównego modułu systemu występuje potrzeba ich wcześniejszej transformacji lub obróbki (pre-processing danych).  Rysunek 10: Model systemu transformującego  3 SYSTEMY HYBRYDOWE  15  3.2.3  Systemy luźno związane  W systemach hybrydowych o luźno powiązanej architekturze (rysunek 11) występuje już zjawisko komunikacji pomiędzy modułami. Najczęściej jako medium wymiany danych używane są pliki, w których jeden proces zapisuje wyniki danych inny odczytuje, po czym może nastąpić zamiana. Ważne jest, że komunikacja w tym modelu jest dwustronna. Zaletami takiej architektury jest prostota implementacji, przez co nadają się znakomicie do prototypowania pewnych rozwiązań. Dodatkowa zaleta może być fakt, że taka architektura pozwala na korzystanie z modułów zewnętrznych dostarczonych przez inne osoby lub ﬁrmy. Prostota tego rozwiązania okupiona jest niestety wysokim kosztem komunikacji (odczytu. zapisu na dysku, ewentualnego parsowania danych).  Rysunek 11: Model systemu luźno powiązanego  3.2.4  Systemy zintegorwane  W systemach hybrydowych zintegrowanych przesyłanie informacji pomiędzy modułami odbywa się w pamięci operacyjnej komputera(rysunek 12). Aby możliwe było wykorzystanie tej architektury w systemie hybrydowym, każdy moduł musi zostać zaprojektowany tak, aby umożliwiał komunikację z częściami systemu. Systemy takie są najczęściej dedykowanymi rozwiązaniami, które są projektowane w celu rozwiązanie konkretnego problemu. Ponieważ komunikacja procesów następuje poprzez współdzieloną pamięć operacyjną, zrównoleglenie obliczeń jest czynnością dużo bardziej skomplikowaną niż w przypadku wcześniejszych rozwiązań. Zaleta wykorzystania tej architektury jest mały koszt związany z komunikacją. W rozwiązaniu tym wykorzystuje się również ideę tablicy (blackboard ), jest to ogólnodostępny obszar pamięci, w którym wykonujące się moduły zapisują wyniki swojej pracy, tak aby wszyscy inni mogli z nich natychmiast skorzystać. 3.2.5 Systemy w pełni zintegrowane  W architekturze w pełni zintegrowanego systemu hybrydowego moduły dzielą między sobą zarówno wiedzę jak również struktury danych (rysunek 13). Zdecydowanie się na tą architekturę powoduje bardzo mocne powiązanie każdego modułu z resztą systemu, jednak zaletą jest usunięcie zbytecznej redundancji  3 SYSTEMY HYBRYDOWE  16  Rysunek 12: Model systemu zintegrowanego elementów. Możliwe jest również pełne kontrolowanie jednego modułu przez inny (np. algorytm genetyczny kierujący pracą innego algorytmu genetycznego), co powoduje większe możliwości rozwiązywania problemów. Niewątpliwą wadą takich systemów jest to, że są to rozwiązania ściśle dedykowane pod dany typ problemu i istnieją małe szanse ponownego wykorzystania elementów systemu w innych projektach. Kłopotliwe może być również zapewnienie dostatecznego poziomu równoległości, ze względu na dużą ilość zależności i powiązań międzymodułowych.  Rysunek 13: Model systemu w pełni zintegrowanego  3.3  Modele pracy systemu hybrydowego  Istnieje kilka modeli pracy modułów systemu hybrydowego. Zostały one przedstawione na rysunku 14. Opis sposobów integracji modułów: • Przetwarzanie łańcuchowe - moduł przetwarzania symbolicznego (np. system ekspertowy), odgrywa rolę głównego procesu systemu. Jego praca może być wspierana przez prace przez pre - procesor oraz post-procesor będący np. siecią neuronową. Możliwa jest również konﬁguracja odwrotna. • Meta przetwarzanie - jeden moduł odgrywa rolę głównego procesu rozwiązującego problem inne natomiast pracują w meta - warstwie pełniąc role np. dozorcy, kontrolera wydajności, detektora błędów, w stosunku do procesu w niższej warstwie. • Przetwarzanie wewnętrzne - jeden lub więcej modułów jest osadzonych (wbudowanych) w innych. Praca elementów osadzonych jest koordy-  3 SYSTEMY HYBRYDOWE  17  nowana przez proces główny. • Przetwarzanie wspólne - oba moduły są równorzędnymi partnerami podczas rozwiązywania problemu. Każdy proces może działać bezpośrednio na środowisku, w którym pracują, oraz każdy może transmitować oraz obierać informacje od drugiego.  Rysunek 14: Model przetwarzania w systemach hybrydowych  3.4  Przykładowy system hybrydowy  Tradycyjne systemy ekspertowe podczas swojej pracy manipulują symbolami. Zaletami tego podejścia jest zdolność do zrozumiałej reprezentacji posiadanej wiedzy. Z drugiej zaś strony istnieją sieci neuronowe, w których wiedza zakodowana jest w postaci wag połączeń miedzyneuronowych. Wiedza ta nie jest łatwa do zinterpretowania i zanalizowania. Sieci neuronowe można traktować jak czarne pudełka, które działają, ale ciężko powiedzieć dlaczego i czy na pewno poprawnie. Jednakże sztuczne sieci neuronowe są bardzo potężnym narzędziem używanym do wydobywania (akwizycji) wiedzy z istniejących danych oraz do jej generalizacji. Sieci neuronowe z łatwością radzą sobie z informacją nieścisłą czy niepewną, która dla systemów ekspertowych stanowi poważny problem. Podczas, gdy tradycyjne systemy ekspertowe zostały zaprojektowane do przechowywania wiedzy w postaci reguł (uzyskiwanej od ludzi i przez nich rozumianej), systemy takie jak sieci neuronowe są używane do nauki i generalizowania wiedzy zawartej w praktycznych przypadkach. Połączenie tych dwóch podejść (systemów ekspertowych z sieciami neuronowymi), pozwoliło wykorzystać te dwa komplementarne podejścia w celu zwiększenia efektywności całego  3 SYSTEMY HYBRYDOWE  18  Rysunek 15: Model ideowy połączenia Systemu ekspertowego z siecią neuronową systemu. Wydobycie dodatkowych danych, wcześniej nieosiągalnych pozwoliło podnieść ogólną skuteczność wnioskowania, przy jednoczesnym zachowaniu możliwości objaśniających. Model ideowy takiego systemu ekspertowego został przedstawiony na rysunku 15.  3.5  Kierunki rozwoju systemów hybrydowych  Aby stwierdzić, w jakim kierunku zmierza rozwój systemów hybrydowych, należałoby się przyjrzeć, jakie rozwiązania stosuje się przy konstruowania nowoczesnych systemów sztucznej inteligencji. Niestety informacje te są albo trudno osiągalne, albo wręcz chronione i stanowią tak zwane Know-How ﬁrm. Inną metodą jest porównanie liczby publikacji, jakie ukazują się na świecie z dziedziny systemów hybrydowych. Ilość publikacji na temat różnych rozwiązań świadczyć może zarówno o jego stopniu przydatności jak i o kierunku i potencjalnych przyszłych rozwiązań. Na rysunku 16, można zauważyć, że największa liczba publikacji dotyczy połączenia systemów ekspertowych z sieciami neuronowymi. W następnej kolejności publikowane są artykuły na temat systemów ekspertowych i logiki rozmytej, sieci neuronowej i logiki rozmytej. Najmniejszym zainteresowaniem cieszą się systemy hybrydowe próbujące wykorzystać zalety systemów ekspertowych i algorytmów genetycznych oraz systemy złożone z wielu modułów, to ostatnie podejrzewać można wiąże się z faktem bardzo dużego skomplikowania takich systemów. Nowe kierunki rozwoju systemów hybrydowych, poza badaniem skuteczności różnych połączeń poszczególnych modułów, prowadzą do stworzenia ujednoliconej architektury systemów hybrydowych oraz do standardowych modeli komunikacji. Powstał specjalny język służący komunikacji pracujących w systemie modułów - CHARON. Kolejnym krokiem jest koncepcja systemu wieloagentowego. Na system wie-  3 SYSTEMY HYBRYDOWE  19  Rysunek 16: Ilość prac naukowych na temat systemów hybrydowych loagentowy składają się agenci (niezależne jednostki), egzystujące i wchodzące w interakcje ze środowiskiem, w którym przebywają. Model agenta przedstawiony jest na rysunku 17. Obecnie implementacja systemów hybrydowych odbywa się na klasycznym ogólnodostępnym sprzęcie komputerowym. Kolejnym krokiem na drodze rozwoju systemów hybrydowych jest stworzenie dedykowanych architektur sprzętu (np. jak sterowniki rozmyte czasu rzeczywistego).  Rysunek 17: Model agenta w systemie wieloagentowym  LITERATURA  20  Literatura [1] Michał Białko Podstawowe własności sieci neuronowych i hybrydowych systemów eksperowych. Wydawnictwo Uczelniane Politechniki Koszalińskiej, 2000 [2] Hybrid Intelligent Systems - niebieska książka zalana kawą ;-) [3] Giarratano, Joseph and Riley, Gary. Expert Systems: Principles and Programming. 3rd Edition. PWS Publishing, Boston, MA. 1998. [4] Fernando Osorio Hybrid Systems. P.R.I.S - N.U.S. Singapore, April 2001 [5] Athanosios Tsakonas, George Dounias Hybrid Computational Intelligence Shemes in Complex Domains: An extended review [6] Rajeev Alur, Radu Grosu, Yerang Hur, Vijay Kumar, and Insup Lee Modular Speciﬁcation of Hybrid Systems in Charon URL: http://www.cis.upenn.edu/ alur,grosu,yehur,kumar,lee [7] L´szló Monostori, József Horny´k, Csaba Egresits, Zsolt J´nos Viharos a a a SOFT COMPUTING AND HYBRID AI APPROACHES TO INTELLIGENT MANUFACTURING ieaaie, 1998   &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3353484041434359926?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3353484041434359926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3353484041434359926' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3353484041434359926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3353484041434359926'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/02/sztuczna-inteligencja-systemy-hybrydowe.html' title='Sztuczna Inteligencja - Systemy Hybrydowe'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8501940265041788351</id><published>2009-01-19T16:52:00.003+01:00</published><updated>2009-03-23T11:04:13.033+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inne'/><title type='text'>Negocjacje - Techniki, Strategie</title><content type='html'>Odnalazłem w swoich archiwach dokument, który pisałem jeszcze na początku studiów (więc już dość dawno temu), niemniej jednak myślę że temat jest na tyle ciekawy, że warto udostępnić ten tekst szerszemu gronu odbiorców. Życzę miłej lektury. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Negocjacje.pdf"&gt;Negocjacje - dokument w wersji pdf (290kb)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="View Michal_Stanek-Negocjacje on Scribd" href="http://www.scribd.com/doc/13570147/MichalStanekNegocjacje" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Michal_Stanek-Negocjacje&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_903179631933972" name="doc_903179631933972" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=13570147&amp;access_key=key-2jag5g8yp8i1kb3evgcg&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=13570147&amp;access_key=key-2jag5g8yp8i1kb3evgcg&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_903179631933972_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/Academic-Work/" style="text-decoration: underline;"&gt;Academic Work&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/negocjacje" style="text-decoration: underline;"&gt;negocjacje&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8501940265041788351?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8501940265041788351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8501940265041788351' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8501940265041788351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8501940265041788351'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/01/negocjacje-techniki-strategie.html' title='Negocjacje - Techniki, Strategie'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-768798971085313025</id><published>2009-01-09T01:31:00.007+01:00</published><updated>2009-02-27T06:22:10.970+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>Ubuntu 8.10 Netbeans 6.5 Segmentation Fault</title><content type='html'>My Netbeans stop working on Ubuntu. I try to google the solution but the problem is more complicated than I suppose on the beginning. I investigate many things even hardware problems (but on my gentoo netbeans work absolutely fine), even reinstall system couple of times, back to previous version and install 32bit version. Nothing of those things solve this problem. The strange thing, that the segfault is replicated even if I switched the VM to another vendor for example open-jdk. If any of you experience similar problem please leave a comment. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# An unexpected error has been detected by Java Runtime Environment:&lt;br /&gt;#&lt;br /&gt;#  SIGSEGV (0xb) at pc=0x00007ff970beb5af, pid=20424, tid=1117591888&lt;br /&gt;#&lt;br /&gt;# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0-b16 mixed mode linux-amd64)&lt;br /&gt;# Problematic frame:&lt;br /&gt;# C  [libc.so.6+0x315af]  catgets+0x1f&lt;br /&gt;#&lt;br /&gt;# An error report file with more information is saved as:&lt;br /&gt;# /home/m/netbeans-6.5/bin/hs_err_pid20424.log&lt;br /&gt;#&lt;br /&gt;# If you would like to submit a bug report, please visit:&lt;br /&gt;#   http://java.sun.com/webapps/bugreport/crash.jsp&lt;br /&gt;# The crash happened outside the Java Virtual Machine in native code.&lt;br /&gt;# See problematic frame for where to report the bug.&lt;br /&gt;#&lt;br /&gt;/usr/share/netbeans/6.1/bin/../platform8/lib/nbexec: line 470: 20424 Aborted &lt;br/&gt;&lt;br /&gt;"/usr/lib/jvm/jdk1.6.0_11/bin/java" -Djdk.home="/usr/lib/jvm/jdk1.6.0_11" &lt;br/&gt;&lt;br /&gt;-Djava.library.path=/usr/lib/jni -classpath "/usr/share/netbeans/6.1/platform8/lib/boot.jar:&lt;br /&gt;&lt;br/&gt; /usr/share/netbeans/6.1/platform8/lib/org-openide-modules.jar:/usr/share/netbeans &lt;br/&gt;/6.1/platform8/lib/org-openide-util.jar:/usr/lib/jvm/jdk1.6.0_11/lib/dt.jar:/usr/lib/jvm/jdk1.6.0_11/lib/tools.jar" -Dnetbeans.system_http_proxy="DIRECT"&lt;br/&gt; -Dnetbeans.system_http_non_proxy_hosts="" -Dnetbeans.dirs="/usr/share/netbeans/6.1/nb6.1:/usr/share/netbeans/6.1/ide9:/usr/share/netbeans/6.1/java2:/usr/share/netbeans/6.1/apisupport1:/usr/share/netbeans/6.1/harness:"&lt;br/&gt; -Dnetbeans.home="/usr/share/netbeans/6.1/platform8" '-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade' &lt;br/&gt;'-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense' &lt;span style="font-weight:bold;"&gt;&lt;/span&gt;'-Xmx512m' '-client'&lt;br/&gt; '-Xss2m' '-Xms32m' '-XX:PermSize=32m' '-XX:MaxPermSize=200m' '-Xverify:none' &lt;br/&gt;'-Dapple.laf.useScreenMenuBar=true' '-Dsun.java2d.noddraw=true' &lt;br/&gt;org.netbeans.Main --userdir "/home/m/.netbeans/6.1" "--branding" "nb"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;java -version&lt;br /&gt;java version "1.6.0_10"&lt;br /&gt;Java(TM) SE Runtime Environment (build 1.6.0_10-b33)&lt;br /&gt;Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;m@izmisiek:~/netbeans-6.5/bin$ cat /home/m/netbeans-6.5/bin/hs_err_pid20424.log&lt;br /&gt;#&lt;br /&gt;# An unexpected error has been detected by Java Runtime Environment:&lt;br /&gt;#&lt;br /&gt;#  SIGSEGV (0xb) at pc=0x00007ff970beb5af, pid=20424, tid=1117591888&lt;br /&gt;#&lt;br /&gt;# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0-b16 mixed mode linux-amd64)&lt;br /&gt;# Problematic frame:&lt;br /&gt;# C  [libc.so.6+0x315af]  catgets+0x1f&lt;br /&gt;#&lt;br /&gt;# If you would like to submit a bug report, please visit:&lt;br /&gt;#   http://java.sun.com/webapps/bugreport/crash.jsp&lt;br /&gt;# The crash happened outside the Java Virtual Machine in native code.&lt;br /&gt;# See problematic frame for where to report the bug.&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;---------------  T H R E A D  ---------------&lt;br /&gt;&lt;br /&gt;Current thread (0x00007ff93d7df800):  JavaThread "AWT-EventQueue-0" [_thread_in_native, id=20450, stack(0x00000000427d1000,0x00000000429d2000)]&lt;br /&gt;&lt;br /&gt;siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000000000008&lt;br /&gt;&lt;br /&gt;Registers:&lt;br /&gt;RAX=0x00007ff93f220490, RBX=0x0000000000000001, RCX=0x00007ff93f0f06cd, RDX=0x0000000000000013&lt;br /&gt;RSP=0x00000000429d0008, RBP=0x00007ff93f0f06cd, RSI=0x0000000000000013, RDI=0x0000000000000000&lt;br /&gt;R8 =0x00000000408db350, R9 =0x0000000000000000, R10=0x00000000429cfda0, R11=0x00007ff970beb590&lt;br /&gt;R12=0x0000000000000113, R13=0x00000000408db350, R14=0x000000000000000f, R15=0x00000000429d0520&lt;br /&gt;RIP=0x00007ff970beb5af, EFL=0x0000000000010202, CSGSFS=0x0000000000000033, ERR=0x0000000000000004&lt;br /&gt;  TRAPNO=0x000000000000000e&lt;br /&gt;&lt;br /&gt;Top of Stack: (sp=0x00000000429d0008)&lt;br /&gt;0x00000000429d0008:   00000000408d4280 00000000429d0040&lt;br /&gt;0x00000000429d0018:   00007ff93f04dc36 00000000408db350&lt;br /&gt;0x00000000429d0028:   00007ff93813eae0 00007ff93813eae0&lt;br /&gt;0x00000000429d0038:   00007ff93d7e1aa0 00000000429d0090&lt;br /&gt;0x00000000429d0048:   00007ff93f04e855 0000000000a2e701&lt;br /&gt;0x00000000429d0058:   0000000000000115 000000000001a9a0&lt;br /&gt;0x00000000429d0068:   00000000408db350 00007ff93ef09590&lt;br /&gt;0x00000000429d0078:   0000000000000113 0000000000000115&lt;br /&gt;0x00000000429d0088:   00007ff93d7e1aa0 00007ff93d7df9c0&lt;br /&gt;0x00000000429d0098:   00007ff93ef0969e 00007ff93f20e1f0&lt;br /&gt;0x00000000429d00a8:   00000000429d0130 00000000408d4280&lt;br /&gt;0x00000000429d00b8:   00007ff93ef0a363 00000000429d00e0&lt;br /&gt;0x00000000429d00c8:   00007ff970444c37 0000000000000000&lt;br /&gt;0x00000000429d00d8:   00007ff93814a4a0 00007ff93814a4a0&lt;br /&gt;0x00000000429d00e8:   00000000705ad0c6 00000000408db350&lt;br /&gt;0x00000000429d00f8:   0001000000000000 00007ff93d7e0a20&lt;br /&gt;0x00000000429d0108:   00007ff93d7a7b50 00007ff93ea77120&lt;br /&gt;0x00000000429d0118:   0000000000000000 00000000429d0510&lt;br /&gt;0x00000000429d0128:   0000000000000000 00007ff93e86a192&lt;br /&gt;0x00000000429d0138:   0000000000000000 00007ff93e86a218&lt;br /&gt;0x00000000429d0148:   0000000000000000 00007ff93e86a168&lt;br /&gt;0x00000000429d0158:   00007ff9381422f0 00007ff93e86973a&lt;br /&gt;0x00000000429d0168:   0000000000000020 00007ff93e869743&lt;br /&gt;0x00000000429d0178:   0000000000000018 00007ff93e869865&lt;br /&gt;0x00000000429d0188:   0000000000000000 00007ff93e869a15&lt;br /&gt;0x00000000429d0198:   0000000000000000 00007ff93e869a17&lt;br /&gt;0x00000000429d01a8:   0000000000000000 00007ff93e869a08&lt;br /&gt;0x00000000429d01b8:   0000000000000000 00007ff93e86978a&lt;br /&gt;0x00000000429d01c8:   0000000000000000 00007ff93f0dcb0b&lt;br /&gt;0x00000000429d01d8:   00007ff93d7e18c0 00007ff93f0dcb27&lt;br /&gt;0x00000000429d01e8:   00007ff93d7e1990 00007ff93f0dcb35&lt;br /&gt;0x00000000429d01f8:   00007ff93d7e1a60 00007ff93f0de23f &lt;br /&gt;&lt;br /&gt;Instructions: (pc=0x00007ff970beb5af)&lt;br /&gt;0x00007ff970beb59f:   00 00 83 c6 01 85 f6 7e 76 85 d2 78 72 0f af d6&lt;br /&gt;0x00007ff970beb5af:   4c 8b 47 08 48 8b 4f 18 48 63 d2 4f 8d 1c 40 48 &lt;br /&gt;&lt;br /&gt;Stack: [0x00000000427d1000,0x00000000429d2000],  sp=0x00000000429d0008,  free space=2044k&lt;br /&gt;Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)&lt;br /&gt;C  [libc.so.6+0x315af]  catgets+0x1f&lt;br /&gt;&lt;br /&gt;Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)&lt;br /&gt;j  sun.awt.motif.MWindowPeer.pCreate(Lsun/awt/motif/MComponentPeer;Ljava/lang/String;)V+0&lt;br /&gt;j  sun.awt.motif.MWindowPeer.create(Lsun/awt/motif/MComponentPeer;)V+12&lt;br /&gt;j  sun.awt.motif.MComponentPeer.init(Ljava/awt/Component;)V+31&lt;br /&gt;j  sun.awt.motif.MWindowPeer.init(Ljava/awt/Window;)V+102&lt;br /&gt;j  sun.awt.motif.MFramePeer.&lt;init&gt;(Ljava/awt/Frame;)V+159&lt;br /&gt;j  sun.awt.motif.MToolkit.createFrame(Ljava/awt/Frame;)Ljava/awt/peer/FramePeer;+5&lt;br /&gt;j  java.awt.Frame.addNotify()V+20&lt;br /&gt;j  java.awt.Window.pack()V+28&lt;br /&gt;j  org.netbeans.core.startup.Splash.center(Ljava/awt/Window;)V+1&lt;br /&gt;j  org.netbeans.core.startup.Splash$SplashRunner.run()V+11&lt;br /&gt;j  java.awt.event.InvocationEvent.dispatch()V+47&lt;br /&gt;j  java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V+26&lt;br /&gt;j  java.awt.EventDispatchThread.pumpOneEventForFilters(I)Z+204&lt;br /&gt;j  java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V+30&lt;br /&gt;j  java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11&lt;br /&gt;j  java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4&lt;br /&gt;j  java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3&lt;br /&gt;j  java.awt.EventDispatchThread.run()V+9&lt;br /&gt;v  ~StubRoutines::call_stub&lt;br /&gt;&lt;br /&gt;---------------  P R O C E S S  ---------------&lt;br /&gt;&lt;br /&gt;Java Threads: ( =&gt; current thread )&lt;br /&gt;=&gt;0x00007ff93d7df800 JavaThread "AWT-EventQueue-0" [_thread_in_native, id=20450, stack(0x00000000427d1000,0x00000000429d2000)]&lt;br /&gt;  0x00007ff93d7ba400 JavaThread "AWT-Motif" daemon [_thread_blocked, id=20449, stack(0x00000000425d0000,0x00000000427d1000)]&lt;br /&gt;  0x00007ff93d7b5c00 JavaThread "AWT-Shutdown" [_thread_blocked, id=20448, stack(0x00000000423cf000,0x00000000425d0000)]&lt;br /&gt;  0x00007ff938150c00 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=20447, stack(0x00000000421ce000,0x00000000423cf000)]&lt;br /&gt;  0x0000000040868000 JavaThread "Timer-0" daemon [_thread_blocked, id=20446, stack(0x00000000402f0000,0x00000000404f1000)]&lt;br /&gt;  0x00000000408da000 JavaThread "main" [_thread_in_vm_trans, id=20445, stack(0x0000000041fcd000,0x00000000421ce000)]&lt;br /&gt;  0x0000000040948400 JavaThread "Active Reference Queue Daemon" daemon [_thread_blocked, id=20436, stack(0x0000000040d23000,0x0000000040f24000)]&lt;br /&gt;  0x000000004084ec00 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=20434, stack(0x000000004181d000,0x0000000041a1e000)]&lt;br /&gt;  0x000000004084c000 JavaThread "CompilerThread1" daemon [_thread_blocked, id=20433, stack(0x000000004171c000,0x000000004181d000)]&lt;br /&gt;  0x0000000040848400 JavaThread "CompilerThread0" daemon [_thread_in_native, id=20432, stack(0x00000000414ec000,0x00000000415ed000)]&lt;br /&gt;  0x0000000040846400 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=20431, stack(0x00000000412eb000,0x00000000414ec000)]&lt;br /&gt;  0x0000000040827400 JavaThread "Finalizer" daemon [_thread_blocked, id=20430, stack(0x0000000041ccb000,0x0000000041ecc000)]&lt;br /&gt;  0x0000000040820000 JavaThread "Reference Handler" daemon [_thread_blocked, id=20429, stack(0x0000000041aca000,0x0000000041ccb000)]&lt;br /&gt;  0x0000000040799c00 JavaThread "main" [_thread_blocked, id=20425, stack(0x0000000040b22000,0x0000000040d23000)]&lt;br /&gt;&lt;br /&gt;Other Threads:&lt;br /&gt;  0x000000004081a800 VMThread [stack: 0x000000004161b000,0x000000004171c000] [id=20428]&lt;br /&gt;  0x0000000040851000 WatcherThread [stack: 0x0000000041ecc000,0x0000000041fcd000] [id=20435]&lt;br /&gt;&lt;br /&gt;VM state:not at safepoint (normal execution)&lt;br /&gt;&lt;br /&gt;VM Mutex/Monitor currently owned by a thread: None&lt;br /&gt;&lt;br /&gt;Heap&lt;br /&gt; PSYoungGen      total 9536K, used 5956K [0x00007ff9616d0000, 0x00007ff962170000, 0x00007ff96c170000)&lt;br /&gt;  eden space 8192K, 72% used [0x00007ff9616d0000,0x00007ff961ca13e0,0x00007ff961ed0000)&lt;br /&gt;  from space 1344K, 0% used [0x00007ff962020000,0x00007ff962020000,0x00007ff962170000)&lt;br /&gt;  to   space 1344K, 0% used [0x00007ff961ed0000,0x00007ff961ed0000,0x00007ff962020000)&lt;br /&gt; PSOldGen        total 21888K, used 0K [0x00007ff94c170000, 0x00007ff94d6d0000, 0x00007ff9616d0000)&lt;br /&gt;  object space 21888K, 0% used [0x00007ff94c170000,0x00007ff94c170000,0x00007ff94d6d0000)&lt;br /&gt; PSPermGen       total 32768K, used 10263K [0x00007ff93f970000, 0x00007ff941970000, 0x00007ff94c170000)&lt;br /&gt;  object space 32768K, 31% used [0x00007ff93f970000,0x00007ff940375d30,0x00007ff941970000)&lt;br /&gt;&lt;br /&gt;Dynamic libraries:&lt;br /&gt;40000000-40009000 r-xp 00000000 08:01 168553                             /usr/lib/jvm/jdk1.6.0_11/bin/java&lt;br /&gt;40108000-4010a000 rwxp 00008000 08:01 168553                             /usr/lib/jvm/jdk1.6.0_11/bin/java&lt;br /&gt;402f0000-402f3000 ---p 402f0000 00:00 0 &lt;br /&gt;402f3000-404f1000 rwxp 402f3000 00:00 0 &lt;br /&gt;40791000-40b0e000 rwxp 40791000 00:00 0                                  [heap]&lt;br /&gt;40b22000-40b25000 ---p 40b22000 00:00 0 &lt;br /&gt;40b25000-40d23000 rwxp 40b25000 00:00 0 &lt;br /&gt;40d23000-40d26000 ---p 40d23000 00:00 0 &lt;br /&gt;40d26000-40f24000 rwxp 40d26000 00:00 0 &lt;br /&gt;410e9000-410ea000 ---p 410e9000 00:00 0 &lt;br /&gt;410ea000-411ea000 rwxp 410ea000 00:00 0 &lt;br /&gt;411ea000-411eb000 ---p 411ea000 00:00 0 &lt;br /&gt;411eb000-412eb000 rwxp 411eb000 00:00 0 &lt;br /&gt;412eb000-412ee000 ---p 412eb000 00:00 0 &lt;br /&gt;412ee000-414ec000 rwxp 412ee000 00:00 0 &lt;br /&gt;414ec000-414ef000 ---p 414ec000 00:00 0 &lt;br /&gt;414ef000-415ed000 rwxp 414ef000 00:00 0 &lt;br /&gt;4161b000-4161c000 ---p 4161b000 00:00 0 &lt;br /&gt;4161c000-4171c000 rwxp 4161c000 00:00 0 &lt;br /&gt;4171c000-4171f000 ---p 4171c000 00:00 0 &lt;br /&gt;4171f000-4181d000 rwxp 4171f000 00:00 0 &lt;br /&gt;4181d000-41820000 ---p 4181d000 00:00 0 &lt;br /&gt;41820000-41a1e000 rwxp 41820000 00:00 0 &lt;br /&gt;41aca000-41acd000 ---p 41aca000 00:00 0 &lt;br /&gt;41acd000-41ccb000 rwxp 41acd000 00:00 0 &lt;br /&gt;41ccb000-41cce000 ---p 41ccb000 00:00 0 &lt;br /&gt;41cce000-41ecc000 rwxp 41cce000 00:00 0 &lt;br /&gt;41ecc000-41ecd000 ---p 41ecc000 00:00 0 &lt;br /&gt;41ecd000-41fcd000 rwxp 41ecd000 00:00 0 &lt;br /&gt;41fcd000-41fd0000 ---p 41fcd000 00:00 0 &lt;br /&gt;41fd0000-421ce000 rwxp 41fd0000 00:00 0 &lt;br /&gt;421ce000-421d1000 ---p 421ce000 00:00 0 &lt;br /&gt;421d1000-423cf000 rwxp 421d1000 00:00 0 &lt;br /&gt;423cf000-423d2000 ---p 423cf000 00:00 0 &lt;br /&gt;423d2000-425d0000 rwxp 423d2000 00:00 0 &lt;br /&gt;425d0000-425d3000 ---p 425d0000 00:00 0 &lt;br /&gt;425d3000-427d1000 rwxp 425d3000 00:00 0 &lt;br /&gt;427d1000-427d4000 ---p 427d1000 00:00 0 &lt;br /&gt;427d4000-429d2000 rwxp 427d4000 00:00 0 &lt;br /&gt;7ff938000000-7ff9381f2000 rwxp 7ff938000000 00:00 0 &lt;br /&gt;7ff9381f2000-7ff93c000000 ---p 7ff9381f2000 00:00 0 &lt;br /&gt;7ff93cbb6000-7ff93cbbb000 r-xp 00000000 08:01 8936                       /usr/lib/libXfixes.so.3.1.0&lt;br /&gt;7ff93cbbb000-7ff93cdba000 ---p 00005000 08:01 8936                       /usr/lib/libXfixes.so.3.1.0&lt;br /&gt;7ff93cdba000-7ff93cdbb000 rwxp 00004000 08:01 8936                       /usr/lib/libXfixes.so.3.1.0&lt;br /&gt;7ff93cdbb000-7ff93cdc4000 r-xp 00000000 08:01 8956                       /usr/lib/libXrender.so.1.3.0&lt;br /&gt;7ff93cdc4000-7ff93cfc3000 ---p 00009000 08:01 8956                       /usr/lib/libXrender.so.1.3.0&lt;br /&gt;7ff93cfc3000-7ff93cfc4000 r-xp 00008000 08:01 8956                       /usr/lib/libXrender.so.1.3.0&lt;br /&gt;7ff93cfc4000-7ff93cfc5000 rwxp 00009000 08:01 8956                       /usr/lib/libXrender.so.1.3.0&lt;br /&gt;7ff93cfc5000-7ff93cfce000 r-xp 00000000 08:01 8926                       /usr/lib/libXcursor.so.1.0.2&lt;br /&gt;7ff93cfce000-7ff93d1ce000 ---p 00009000 08:01 8926                       /usr/lib/libXcursor.so.1.0.2&lt;br /&gt;7ff93d1ce000-7ff93d1cf000 rwxp 00009000 08:01 8926                       /usr/lib/libXcursor.so.1.0.2&lt;br /&gt;7ff93d1cf000-7ff93d1d6000 r-xp 00000000 08:01 169087                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnio.so&lt;br /&gt;7ff93d1d6000-7ff93d2d5000 ---p 00007000 08:01 169087                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnio.so&lt;br /&gt;7ff93d2d5000-7ff93d2d7000 rwxp 00006000 08:01 169087                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnio.so&lt;br /&gt;7ff93d2d7000-7ff93d2ea000 r-xp 00000000 08:01 169086                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnet.so&lt;br /&gt;7ff93d2ea000-7ff93d3eb000 ---p 00013000 08:01 169086                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnet.so&lt;br /&gt;7ff93d3eb000-7ff93d3ee000 rwxp 00014000 08:01 169086                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libnet.so&lt;br /&gt;7ff93d3ee000-7ff93d46c000 r-xp 00000000 08:01 169095                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libfontmanager.so&lt;br /&gt;7ff93d46c000-7ff93d56e000 ---p 0007e000 08:01 169095                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libfontmanager.so&lt;br /&gt;7ff93d56e000-7ff93d584000 rwxp 00080000 08:01 169095                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libfontmanager.so&lt;br /&gt;7ff93d584000-7ff93d595000 rwxp 7ff93d584000 00:00 0 &lt;br /&gt;7ff93d595000-7ff93d59a000 r-xp 00000000 08:01 8930                       /usr/lib/libXdmcp.so.6.0.0&lt;br /&gt;7ff93d59a000-7ff93d799000 ---p 00005000 08:01 8930                       /usr/lib/libXdmcp.so.6.0.0&lt;br /&gt;7ff93d799000-7ff93d79a000 rwxp 00004000 08:01 8930                       /usr/lib/libXdmcp.so.6.0.0&lt;br /&gt;7ff93d79a000-7ff93d89a000 rwxp 7ff93d79a000 00:00 0 &lt;br /&gt;7ff93d8c0000-7ff93d8db000 r-xp 00000000 08:01 9863                       /usr/lib/libxcb.so.1.0.0&lt;br /&gt;7ff93d8db000-7ff93dada000 ---p 0001b000 08:01 9863                       /usr/lib/libxcb.so.1.0.0&lt;br /&gt;7ff93dada000-7ff93dadb000 r-xp 0001a000 08:01 9863                       /usr/lib/libxcb.so.1.0.0&lt;br /&gt;7ff93dadb000-7ff93dadc000 rwxp 0001b000 08:01 9863                       /usr/lib/libxcb.so.1.0.0&lt;br /&gt;7ff93dadc000-7ff93dadd000 r-xp 00000000 08:01 9861                       /usr/lib/libxcb-xlib.so.0.0.0&lt;br /&gt;7ff93dadd000-7ff93dcdc000 ---p 00001000 08:01 9861                       /usr/lib/libxcb-xlib.so.0.0.0&lt;br /&gt;7ff93dcdc000-7ff93dcdd000 r-xp 00000000 08:01 9861                       /usr/lib/libxcb-xlib.so.0.0.0&lt;br /&gt;7ff93dcdd000-7ff93dcde000 rwxp 00001000 08:01 9861                       /usr/lib/libxcb-xlib.so.0.0.0&lt;br /&gt;7ff93dcde000-7ff93dcf5000 r-xp 00000000 08:01 8878                       /usr/lib/libICE.so.6.3.0&lt;br /&gt;7ff93dcf5000-7ff93def4000 ---p 00017000 08:01 8878                       /usr/lib/libICE.so.6.3.0&lt;br /&gt;7ff93def4000-7ff93def6000 rwxp 00016000 08:01 8878                       /usr/lib/libICE.so.6.3.0&lt;br /&gt;7ff93def6000-7ff93def9000 rwxp 7ff93def6000 00:00 0 &lt;br /&gt;7ff93def9000-7ff93df01000 r-xp 00000000 08:01 8907                       /usr/lib/libSM.so.6.0.0&lt;br /&gt;7ff93df01000-7ff93e100000 ---p 00008000 08:01 8907                       /usr/lib/libSM.so.6.0.0&lt;br /&gt;7ff93e100000-7ff93e101000 r-xp 00007000 08:01 8907                       /usr/lib/libSM.so.6.0.0&lt;br /&gt;7ff93e101000-7ff93e102000 rwxp 00008000 08:01 8907                       /usr/lib/libSM.so.6.0.0&lt;br /&gt;7ff93e102000-7ff93e104000 r-xp 00000000 08:01 8919                       /usr/lib/libXau.so.6.0.0&lt;br /&gt;7ff93e104000-7ff93e303000 ---p 00002000 08:01 8919                       /usr/lib/libXau.so.6.0.0&lt;br /&gt;7ff93e303000-7ff93e304000 rwxp 00001000 08:01 8919                       /usr/lib/libXau.so.6.0.0&lt;br /&gt;7ff93e304000-7ff93e30d000 r-xp 00000000 08:01 8942                       /usr/lib/libXi.so.6.0.0&lt;br /&gt;7ff93e30d000-7ff93e50d000 ---p 00009000 08:01 8942                       /usr/lib/libXi.so.6.0.0&lt;br /&gt;7ff93e50d000-7ff93e50e000 r-xp 00009000 08:01 8942                       /usr/lib/libXi.so.6.0.0&lt;br /&gt;7ff93e50e000-7ff93e50f000 rwxp 0000a000 08:01 8942                       /usr/lib/libXi.so.6.0.0&lt;br /&gt;7ff93e50f000-7ff93e612000 r-xp 00000000 08:01 14916                      /usr/lib/libX11.so.6.2.0&lt;br /&gt;7ff93e612000-7ff93e812000 ---p 00103000 08:01 14916                      /usr/lib/libX11.so.6.2.0&lt;br /&gt;7ff93e812000-7ff93e813000 r-xp 00103000 08:01 14916                      /usr/lib/libX11.so.6.2.0&lt;br /&gt;7ff93e813000-7ff93e817000 rwxp 00104000 08:01 14916                      /usr/lib/libX11.so.6.2.0&lt;br /&gt;7ff93e817000-7ff93e874000 r-xp 00000000 08:01 8960                       /usr/lib/libXt.so.6.0.0&lt;br /&gt;7ff93e874000-7ff93ea74000 ---p 0005d000 08:01 8960                       /usr/lib/libXt.so.6.0.0&lt;br /&gt;7ff93ea74000-7ff93ea7a000 rwxp 0005d000 08:01 8960                       /usr/lib/libXt.so.6.0.0&lt;br /&gt;7ff93ea7a000-7ff93ea7b000 rwxp 7ff93ea7a000 00:00 0 &lt;br /&gt;7ff93ea7b000-7ff93ea8b000 r-xp 00000000 08:01 8934                       /usr/lib/libXext.so.6.4.0&lt;br /&gt;7ff93ea8b000-7ff93ec8b000 ---p 00010000 08:01 8934                       /usr/lib/libXext.so.6.4.0&lt;br /&gt;7ff93ec8b000-7ff93ec8d000 rwxp 00010000 08:01 8934                       /usr/lib/libXext.so.6.4.0&lt;br /&gt;7ff93ec8d000-7ff93ec92000 r-xp 00000000 08:01 8962                       /usr/lib/libXtst.so.6.1.0&lt;br /&gt;7ff93ec92000-7ff93ee92000 ---p 00005000 08:01 8962                       /usr/lib/libXtst.so.6.1.0&lt;br /&gt;7ff93ee92000-7ff93ee93000 rwxp 00005000 08:01 8962                       /usr/lib/libXtst.so.6.1.0&lt;br /&gt;7ff93eea6000-7ff93f10d000 r-xp 00000000 08:01 169106                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/motif21/libmawt.so&lt;br /&gt;7ff93f10d000-7ff93f20e000 ---p 00267000 08:01 169106                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/motif21/libmawt.so&lt;br /&gt;7ff93f20e000-7ff93f262000 rwxp 00268000 08:01 169106                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/motif21/libmawt.so&lt;br /&gt;7ff93f262000-7ff93f265000 rwxp 7ff93f262000 00:00 0 &lt;br /&gt;7ff93f265000-7ff93f2ef000 r-xp 00000000 08:01 169128                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libawt.so&lt;br /&gt;7ff93f2ef000-7ff93f3ee000 ---p 0008a000 08:01 169128                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libawt.so&lt;br /&gt;7ff93f3ee000-7ff93f406000 rwxp 00089000 08:01 169128                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libawt.so&lt;br /&gt;7ff93f406000-7ff93f42b000 rwxp 7ff93f406000 00:00 0 &lt;br /&gt;7ff93f42b000-7ff93f489000 r-xs 00b8b000 08:01 169475                     /usr/lib/jvm/jdk1.6.0_11/lib/tools.jar&lt;br /&gt;7ff93f489000-7ff93f490000 r-xs 00000000 08:01 11672                      /usr/lib/gconv/gconv-modules.cache&lt;br /&gt;7ff93f490000-7ff93f4cf000 r-xp 00000000 08:01 12899                      /usr/lib/locale/pl_PL.utf8/LC_CTYPE&lt;br /&gt;7ff93f4cf000-7ff93f544000 rwxp 7ff93f4cf000 00:00 0 &lt;br /&gt;7ff93f544000-7ff93f6d4000 r-xs 02ef0000 08:01 169188                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/rt.jar&lt;br /&gt;7ff93f6d4000-7ff93f70c000 rwxp 7ff93f6d4000 00:00 0 &lt;br /&gt;7ff93f70c000-7ff93f760000 rwxp 7ff93f70c000 00:00 0 &lt;br /&gt;7ff93f760000-7ff93f76b000 rwxp 7ff93f760000 00:00 0 &lt;br /&gt;7ff93f76b000-7ff93f80b000 rwxp 7ff93f76b000 00:00 0 &lt;br /&gt;7ff93f80b000-7ff93f81b000 rwxp 7ff93f80b000 00:00 0 &lt;br /&gt;7ff93f81b000-7ff93f86f000 rwxp 7ff93f81b000 00:00 0 &lt;br /&gt;7ff93f86f000-7ff93f87a000 rwxp 7ff93f86f000 00:00 0 &lt;br /&gt;7ff93f87a000-7ff93f919000 rwxp 7ff93f87a000 00:00 0 &lt;br /&gt;7ff93f919000-7ff93f91f000 rwxp 7ff93f919000 00:00 0 &lt;br /&gt;7ff93f91f000-7ff93f96f000 rwxp 7ff93f91f000 00:00 0 &lt;br /&gt;7ff93f96f000-7ff941970000 rwxp 7ff93f96f000 00:00 0 &lt;br /&gt;7ff941970000-7ff94c170000 rwxp 7ff941970000 00:00 0 &lt;br /&gt;7ff94c170000-7ff94d6d0000 rwxp 7ff94c170000 00:00 0 &lt;br /&gt;7ff94d6d0000-7ff9616d0000 rwxp 7ff94d6d0000 00:00 0 &lt;br /&gt;7ff9616d0000-7ff962170000 rwxp 7ff9616d0000 00:00 0 &lt;br /&gt;7ff962170000-7ff96c170000 rwxp 7ff962170000 00:00 0 &lt;br /&gt;7ff96c17c000-7ff96c3ec000 rwxp 7ff96c17c000 00:00 0 &lt;br /&gt;7ff96c3ec000-7ff96f17c000 rwxp 7ff96c3ec000 00:00 0 &lt;br /&gt;7ff96f17c000-7ff96f18a000 r-xp 00000000 08:01 169097                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libzip.so&lt;br /&gt;7ff96f18a000-7ff96f28c000 ---p 0000e000 08:01 169097                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libzip.so&lt;br /&gt;7ff96f28c000-7ff96f28f000 rwxp 00010000 08:01 169097                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libzip.so&lt;br /&gt;7ff96f28f000-7ff96f290000 rwxp 7ff96f28f000 00:00 0 &lt;br /&gt;7ff96f290000-7ff96f2b9000 r-xp 00000000 08:01 169110                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libjava.so&lt;br /&gt;7ff96f2b9000-7ff96f3b8000 ---p 00029000 08:01 169110                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libjava.so&lt;br /&gt;7ff96f3b8000-7ff96f3bf000 rwxp 00028000 08:01 169110                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libjava.so&lt;br /&gt;7ff96f3bf000-7ff96f3cc000 r-xp 00000000 08:01 169092                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libverify.so&lt;br /&gt;7ff96f3cc000-7ff96f4cb000 ---p 0000d000 08:01 169092                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libverify.so&lt;br /&gt;7ff96f4cb000-7ff96f4ce000 rwxp 0000c000 08:01 169092                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/libverify.so&lt;br /&gt;7ff96f4ce000-7ff96f4d9000 r-xp 00000000 08:01 2539                       /lib/libnss_files-2.8.90.so&lt;br /&gt;7ff96f4d9000-7ff96f6d8000 ---p 0000b000 08:01 2539                       /lib/libnss_files-2.8.90.so&lt;br /&gt;7ff96f6d8000-7ff96f6d9000 r-xp 0000a000 08:01 2539                       /lib/libnss_files-2.8.90.so&lt;br /&gt;7ff96f6d9000-7ff96f6da000 rwxp 0000b000 08:01 2539                       /lib/libnss_files-2.8.90.so&lt;br /&gt;7ff96f6da000-7ff96f6e4000 r-xp 00000000 08:01 2549                       /lib/libnss_nis-2.8.90.so&lt;br /&gt;7ff96f6e4000-7ff96f8e3000 ---p 0000a000 08:01 2549                       /lib/libnss_nis-2.8.90.so&lt;br /&gt;7ff96f8e3000-7ff96f8e4000 r-xp 00009000 08:01 2549                       /lib/libnss_nis-2.8.90.so&lt;br /&gt;7ff96f8e4000-7ff96f8e5000 rwxp 0000a000 08:01 2549                       /lib/libnss_nis-2.8.90.so&lt;br /&gt;7ff96f8e5000-7ff96f8ed000 r-xp 00000000 08:01 2535                       /lib/libnss_compat-2.8.90.so&lt;br /&gt;7ff96f8ed000-7ff96faec000 ---p 00008000 08:01 2535                       /lib/libnss_compat-2.8.90.so&lt;br /&gt;7ff96faec000-7ff96faed000 r-xp 00007000 08:01 2535                       /lib/libnss_compat-2.8.90.so&lt;br /&gt;7ff96faed000-7ff96faee000 rwxp 00008000 08:01 2535                       /lib/libnss_compat-2.8.90.so&lt;br /&gt;7ff96faee000-7ff96fb04000 r-xp 00000000 08:01 2533                       /lib/libnsl-2.8.90.so&lt;br /&gt;7ff96fb04000-7ff96fd03000 ---p 00016000 08:01 2533                       /lib/libnsl-2.8.90.so&lt;br /&gt;7ff96fd03000-7ff96fd04000 r-xp 00015000 08:01 2533                       /lib/libnsl-2.8.90.so&lt;br /&gt;7ff96fd04000-7ff96fd05000 rwxp 00016000 08:01 2533                       /lib/libnsl-2.8.90.so&lt;br /&gt;7ff96fd05000-7ff96fd07000 rwxp 7ff96fd05000 00:00 0 &lt;br /&gt;7ff96fd07000-7ff96fd0e000 r-xp 00000000 08:01 169099                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/native_threads/libhpi.so&lt;br /&gt;7ff96fd0e000-7ff96fe0f000 ---p 00007000 08:01 169099                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/native_threads/libhpi.so&lt;br /&gt;7ff96fe0f000-7ff96fe11000 rwxp 00008000 08:01 169099                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/native_threads/libhpi.so&lt;br /&gt;7ff96fe11000-7ff96fe12000 rwxp 7ff96fe11000 00:00 0 &lt;br /&gt;7ff96fe12000-7ff96fe1a000 r-xp 00000000 08:01 2575                       /lib/librt-2.8.90.so&lt;br /&gt;7ff96fe1a000-7ff970019000 ---p 00008000 08:01 2575                       /lib/librt-2.8.90.so&lt;br /&gt;7ff970019000-7ff97001a000 r-xp 00007000 08:01 2575                       /lib/librt-2.8.90.so&lt;br /&gt;7ff97001a000-7ff97001b000 rwxp 00008000 08:01 2575                       /lib/librt-2.8.90.so&lt;br /&gt;7ff97001b000-7ff97009f000 r-xp 00000000 08:01 2526                       /lib/libm-2.8.90.so&lt;br /&gt;7ff97009f000-7ff97029e000 ---p 00084000 08:01 2526                       /lib/libm-2.8.90.so&lt;br /&gt;7ff97029e000-7ff97029f000 r-xp 00083000 08:01 2526                       /lib/libm-2.8.90.so&lt;br /&gt;7ff97029f000-7ff9702a0000 rwxp 00084000 08:01 2526                       /lib/libm-2.8.90.so&lt;br /&gt;7ff9702a0000-7ff97092d000 r-xp 00000000 08:01 169116                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/server/libjvm.so&lt;br /&gt;7ff97092d000-7ff970a2c000 ---p 0068d000 08:01 169116                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/server/libjvm.so&lt;br /&gt;7ff970a2c000-7ff970b7d000 rwxp 0068c000 08:01 169116                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/server/libjvm.so&lt;br /&gt;7ff970b7d000-7ff970bba000 rwxp 7ff970b7d000 00:00 0 &lt;br /&gt;7ff970bba000-7ff970d23000 r-xp 00000000 08:01 2492                       /lib/libc-2.8.90.so&lt;br /&gt;7ff970d23000-7ff970f22000 ---p 00169000 08:01 2492                       /lib/libc-2.8.90.so&lt;br /&gt;7ff970f22000-7ff970f26000 r-xp 00168000 08:01 2492                       /lib/libc-2.8.90.so&lt;br /&gt;7ff970f26000-7ff970f27000 rwxp 0016c000 08:01 2492                       /lib/libc-2.8.90.so&lt;br /&gt;7ff970f27000-7ff970f2c000 rwxp 7ff970f27000 00:00 0 &lt;br /&gt;7ff970f2c000-7ff970f2e000 r-xp 00000000 08:01 2507                       /lib/libdl-2.8.90.so&lt;br /&gt;7ff970f2e000-7ff97112e000 ---p 00002000 08:01 2507                       /lib/libdl-2.8.90.so&lt;br /&gt;7ff97112e000-7ff97112f000 r-xp 00002000 08:01 2507                       /lib/libdl-2.8.90.so&lt;br /&gt;7ff97112f000-7ff971130000 rwxp 00003000 08:01 2507                       /lib/libdl-2.8.90.so&lt;br /&gt;7ff971130000-7ff971147000 r-xp 00000000 08:01 2569                       /lib/libpthread-2.8.90.so&lt;br /&gt;7ff971147000-7ff971346000 ---p 00017000 08:01 2569                       /lib/libpthread-2.8.90.so&lt;br /&gt;7ff971346000-7ff971347000 r-xp 00016000 08:01 2569                       /lib/libpthread-2.8.90.so&lt;br /&gt;7ff971347000-7ff971348000 rwxp 00017000 08:01 2569                       /lib/libpthread-2.8.90.so&lt;br /&gt;7ff971348000-7ff97134c000 rwxp 7ff971348000 00:00 0 &lt;br /&gt;7ff97134c000-7ff97136b000 r-xp 00000000 08:01 2472                       /lib/ld-2.8.90.so&lt;br /&gt;7ff971371000-7ff971377000 r-xs 0001e000 08:01 169477                     /usr/lib/jvm/jdk1.6.0_11/lib/dt.jar&lt;br /&gt;7ff971377000-7ff97137e000 r-xs 0007e000 08:01 140109                     /usr/share/netbeans/platform8/lib/org-openide-util.jar&lt;br /&gt;7ff97137e000-7ff97137f000 r-xs 00004000 08:01 140110                     /usr/share/netbeans/platform8/lib/org-openide-modules.jar&lt;br /&gt;7ff97137f000-7ff971380000 r-xs 0003b000 08:01 140981                     /usr/share/netbeans/6.1/nb6.1/core/locale/core_nb.jar&lt;br /&gt;7ff971380000-7ff971382000 r-xs 00037000 08:01 140982                     /usr/share/netbeans/6.1/nb6.1/core/org-netbeans-upgrader.jar&lt;br /&gt;7ff971382000-7ff971387000 r-xs 00065000 08:01 140106                     /usr/share/netbeans/platform8/core/org-openide-filesystems.jar&lt;br /&gt;7ff971387000-7ff971391000 rwxp 7ff971387000 00:00 0 &lt;br /&gt;7ff971391000-7ff971447000 rwxp 7ff971391000 00:00 0 &lt;br /&gt;7ff971447000-7ff971449000 rwxp 7ff971447000 00:00 0 &lt;br /&gt;7ff971449000-7ff971450000 r-xp 00000000 08:01 169082                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/jli/libjli.so&lt;br /&gt;7ff971450000-7ff971551000 ---p 00007000 08:01 169082                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/jli/libjli.so&lt;br /&gt;7ff971551000-7ff971553000 rwxp 00008000 08:01 169082                     /usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/jli/libjli.so&lt;br /&gt;7ff971553000-7ff971554000 rwxp 7ff971553000 00:00 0 &lt;br /&gt;7ff971555000-7ff97155a000 r-xs 00087000 08:01 140107                     /usr/share/netbeans/platform8/core/core.jar&lt;br /&gt;7ff97155a000-7ff97155d000 r-xs 00034000 08:01 140111                     /usr/share/netbeans/platform8/lib/boot.jar&lt;br /&gt;7ff97155d000-7ff971565000 rwxs 00000000 08:01 871                        /tmp/hsperfdata_m/20424&lt;br /&gt;7ff971565000-7ff971566000 rwxp 7ff971565000 00:00 0 &lt;br /&gt;7ff971566000-7ff971567000 r-xp 7ff971566000 00:00 0 &lt;br /&gt;7ff971567000-7ff97156a000 rwxp 7ff971567000 00:00 0 &lt;br /&gt;7ff97156a000-7ff97156b000 r-xp 0001e000 08:01 2472                       /lib/ld-2.8.90.so&lt;br /&gt;7ff97156b000-7ff97156c000 rwxp 0001f000 08:01 2472                       /lib/ld-2.8.90.so&lt;br /&gt;7fff79557000-7fff7956c000 rwxp 7ffffffea000 00:00 0                      [stack]&lt;br /&gt;7fff795ff000-7fff79600000 r-xp 7fff795ff000 00:00 0                      [vdso]&lt;br /&gt;ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]&lt;br /&gt;&lt;br /&gt;VM Arguments:&lt;br /&gt;jvm_args: -Djdk.home=/usr/lib/jvm/jdk1.6.0_11 -Djava.library.path=/usr/lib/jni -Dnetbeans.system_http_proxy=DIRECT -Dnetbeans.system_http_non_proxy_hosts= -Dnetbeans.dirs=/usr/share/netbeans/6.1/nb6.1:/usr/share/netbeans/6.1/ide9:/usr/share/netbeans/6.1/java2:/usr/share/netbeans/6.1/apisupport1:/usr/share/netbeans/6.1/harness: -Dnetbeans.home=/usr/share/netbeans/6.1/platform8 -Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade -Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense -Xmx512m -Xss2m -Xms32m -XX:PermSize=32m -XX:MaxPermSize=200m -Xverify:none -Dapple.laf.useScreenMenuBar=true -Dsun.java2d.noddraw=true &lt;br /&gt;java_command: org.netbeans.Main --userdir /home/m/.netbeans/6.1 --branding nb&lt;br /&gt;Launcher Type: SUN_STANDARD&lt;br /&gt;&lt;br /&gt;Environment Variables:&lt;br /&gt;PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games&lt;br /&gt;USERNAME=m&lt;br /&gt;LD_LIBRARY_PATH=/usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64/server:/usr/lib/jvm/jdk1.6.0_11/jre/lib/amd64:/usr/lib/jvm/jdk1.6.0_11/jre/../lib/amd64&lt;br /&gt;SHELL=/bin/bash&lt;br /&gt;DISPLAY=:0.0&lt;br /&gt;&lt;br /&gt;Signal Handlers:&lt;br /&gt;SIGSEGV: [libjvm.so+0x5fcb80], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGBUS: [libjvm.so+0x5fcb80], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGFPE: [libjvm.so+0x4e0d10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGPIPE: [libjvm.so+0x4e0d10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGXFSZ: [libjvm.so+0x4e0d10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGILL: [libjvm.so+0x4e0d10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000&lt;br /&gt;SIGUSR2: [libjvm.so+0x4e3430], sa_mask[0]=0x00000000, sa_flags=0x10000004&lt;br /&gt;SIGHUP: [libjvm.so+0x4e3180], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGINT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000&lt;br /&gt;SIGTERM: [libjvm.so+0x4e3180], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;SIGQUIT: [libjvm.so+0x4e3180], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---------------  S Y S T E M  ---------------&lt;br /&gt;&lt;br /&gt;OS:lenny/sid&lt;br /&gt;&lt;br /&gt;uname:Linux 2.6.27-9-generic #1 SMP Thu Nov 20 22:15:32 UTC 2008 x86_64&lt;br /&gt;libc:glibc 2.8.90 NPTL 2.8.90 &lt;br /&gt;rlimit: STACK 8192k, CORE 0k, NPROC 40448, NOFILE 1024, AS infinity&lt;br /&gt;load average:0.43 0.82 0.61&lt;br /&gt;&lt;br /&gt;CPU:total 2 (2 cores per cpu, 1 threads per core) family 6 model 7 stepping 6, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3&lt;br /&gt;&lt;br /&gt;Memory: 4k page, physical 3988812k(1149728k free), swap 4883752k(4883752k free)&lt;br /&gt;&lt;br /&gt;vm_info: Java HotSpot(TM) 64-Bit Server VM (11.0-b16) for linux-amd64 JRE (1.6.0_11-b03), built on Nov 10 2008 01:28:14 by "java_re" with gcc 3.2.2 (SuSE Linux)&lt;br /&gt;&lt;br /&gt;time: Fri Jan  9 01:26:01 2009&lt;br /&gt;elapsed time: 10 seconds&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-768798971085313025?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/768798971085313025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=768798971085313025' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/768798971085313025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/768798971085313025'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/01/ubuntu-810-netbeans-65-segmentation.html' title='Ubuntu 8.10 Netbeans 6.5 Segmentation Fault'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7170240719752621781</id><published>2009-01-05T21:20:00.002+01:00</published><updated>2009-02-27T06:12:33.814+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Set SUN JDK as default Java Machine in UBUNTU</title><content type='html'>&lt;pre&gt;&lt;br /&gt; sudo update-java-alternatives -s java-6-sun&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7170240719752621781?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7170240719752621781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7170240719752621781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7170240719752621781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7170240719752621781'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/01/set-sun-jdk-as-default-java-machine-in.html' title='Set SUN JDK as default Java Machine in UBUNTU'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8580650513676483640</id><published>2009-01-05T14:01:00.002+01:00</published><updated>2009-01-05T14:02:53.364+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Weighted fulltext search in MySQL</title><content type='html'>&lt;pre&gt;&lt;br /&gt;SELECT&lt;br /&gt;*,&lt;br /&gt;(MATCH (column1) AGAINST ('$query' IN BOOLEAN MODE)*100) +&lt;br /&gt;(MATCH (column2) AGAINST ('$query' IN BOOLEAN MODE)*10) +&lt;br /&gt;MATCH (column3) AGAINST ('$query' IN BOOLEAN MODE) AS rating&lt;br /&gt;FROM&lt;br /&gt;table&lt;br /&gt;WHERE&lt;br /&gt;MATCH (column1,column2,column3) AGAINST ('$query' IN BOOLEAN MODE)&lt;br /&gt;ORDER BY&lt;br /&gt;rating DESC&lt;br /&gt;LIMIT 0,10&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8580650513676483640?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8580650513676483640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8580650513676483640' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8580650513676483640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8580650513676483640'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/01/weighted-fulltext-search-in-mysql.html' title='Weighted fulltext search in MySQL'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6210040889692541598</id><published>2009-01-03T00:57:00.001+01:00</published><updated>2009-01-05T21:32:30.878+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>MPlayer Polskie czcionki</title><content type='html'>Źródło: http://forum.ubuntu.pl/showthread.php?t=38659&lt;br /&gt;&lt;br /&gt;1. Ściągamy potrzebne elementy :&lt;br /&gt;czcionka ttf :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wget &lt;a href="http://aed_221.webpark.pl/subfont.ttf" target="_blank"&gt;http://aed_221.webpark.pl/subfont.ttf&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;czcionka RAW :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wget &lt;a href="http://aed_221.webpark.pl/iso-8859-2-win-1250.zip" target="_blank"&gt;http://aed_221.webpark.pl/iso-8859-2-win-1250.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. Kopiujemy pliki w odpowiednie miejsce :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Katalog na którym pracujemy to :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/home/nazwausera/.mplayer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gdzie nazwausera to : nazwa użytkownika na którym pracujesz. Tworzymy katalog fonts :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mkdir /home/nazwausera/.mplayer/fonts&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Kopiujemy do nowo stworzonego katalogu ściągnięty uprzednio plik subfont.ttf. Teraz zajmiemy się plikiem iso-8859-2-win-1250.zip . Rozpakowujemy go najpierw gdziekolwiek.W rozpakowanym katalogu znajdziemy takie podkatalogi jak : &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;font-arial-##-iso-8859-2&lt;/pre&gt;&lt;br /&gt;gdzie ## to wielkość czcionki jaką chcemy mieć (w moim przypadku wybrałem wielkość 24).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Kopiujemy całą &lt;b&gt;zawartość&lt;/b&gt; wybranego katalogu (w moim przypadku font-arial-24-iso-8859-2) do katalogu &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;/home/nazwausera/.mplayer/fonts&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3.Już jesteśmy blisko.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Odpalamy mplayera i ustawiamy odpowiednio w opcjach:&lt;br /&gt;&lt;br /&gt;Zakładka &amp;#8220;Napisy i OSD&amp;#8221; -&gt; Kodowanie -&gt; CP1250&lt;br /&gt;&lt;br /&gt;Zakładka &amp;#8220;Czcionka&amp;#8221; -&gt; Kodowanie -&gt; Unicode&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Zakładka &amp;#8220;Czcionka&amp;#8221; -&gt; Kodowanie -&gt; u samej góry jest miejsce na ścieżkę do czcionki -&gt; wpisujemy ścieżkę do naszego subfont.ttf czyli :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/home/nazwausera/.mplayer/fonts/subfont.ttf&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4.Klikamy OK i wychodzimy z Mplayera&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Przy kolejnym uruchomieniu cieszymy się polskimi fontami w podpisach filmów&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6210040889692541598?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6210040889692541598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6210040889692541598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6210040889692541598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6210040889692541598'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2009/01/mplayer-polskie-czcionki.html' title='MPlayer Polskie czcionki'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7309660574512200868</id><published>2008-12-28T19:24:00.002+01:00</published><updated>2009-03-15T23:39:33.284+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>MySQL data in /home direcotory</title><content type='html'>(following http://www.debianadmin.com/mysql-database-server-installation-and-configuration-in-ubuntu.html)&lt;br /&gt;&lt;br /&gt;Here is the procedure how to change Mysql default data directory&lt;br /&gt;&lt;br /&gt;By default, MySQL’s datadir is placed in the /var/lib/mysql directory.&lt;br /&gt;&lt;br /&gt;Create the directory that will be new datadir (ex:-/home/db)&lt;br /&gt;&lt;br /&gt;chown the directory to the mysql:mysql user&lt;br /&gt;&lt;br /&gt;sudo chown -R mysql:mysql /home/db/*&lt;br /&gt;&lt;br /&gt;You need to stop the mysql server using the following command&lt;br /&gt;&lt;br /&gt;sudo /etc/init.d/mysql stop&lt;br /&gt;&lt;br /&gt;Now you need to edit the /etc/mysql/my.cnf file&lt;br /&gt;&lt;br /&gt;sudo vi /etc/mysql/my.cnf&lt;br /&gt;&lt;br /&gt;and look for “datadir = /var/lib/mysql” this si where mysql database default data directory here you need to change this one to your new directory&lt;br /&gt;&lt;br /&gt;datadir = /home/db&lt;br /&gt;&lt;br /&gt;copy the files from the old datadir to the new location. However, make sure that the files named&lt;br /&gt;ib_arch_log_0000000000, ib_logfile0 etc. are not copied to the newer location.&lt;br /&gt;&lt;br /&gt;Make sure that the files and directories are owned by mysql user&lt;br /&gt;&lt;br /&gt;Make changes in the my.cnf to point the new datadir.&lt;br /&gt;&lt;br /&gt;Restart the MySQL database&lt;br /&gt;&lt;br /&gt;sudo /etc/init.d/mysql start&lt;br /&gt;&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;Following: http://neodon.blogspot.com/2008/09/changing-data-directory-for-mysql-in.html&lt;br /&gt;&lt;br /&gt;You simply edit /etc/apparmor.d/usr.sbin.mysqld. Underneath the two lines authorizing the default MySQL data directories, add two more with your custom directory. Make sure you have a trailing / on the directory name, otherwise it will not work (I had this problem at first). After this change, restart AppArmor:&lt;br /&gt;&lt;br /&gt;    sudo invoke-rc.d apparmor restart&lt;br /&gt;&lt;br /&gt;Now you should be able to set up the new directory as a MySQL data directory and initialize it using mysql_install_db. For more information on this topic, check out the following links:&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7309660574512200868?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7309660574512200868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7309660574512200868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7309660574512200868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7309660574512200868'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/12/mysql-data-in-home-direcotory.html' title='MySQL data in /home direcotory'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8072576307614958110</id><published>2008-12-04T02:26:00.002+01:00</published><updated>2009-03-15T23:37:49.212+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Wyświetlanie Daty</title><content type='html'>&lt;pre&gt;&lt;br /&gt;strftime:&lt;br /&gt;&lt;br /&gt;  %a - The abbreviated weekday name (``Sun'')&lt;br /&gt;  %A - The  full  weekday  name (``Sunday'')&lt;br /&gt;  %b - The abbreviated month name (``Jan'')&lt;br /&gt;  %B - The  full  month  name (``January'')&lt;br /&gt;  %c - The preferred local date and time representation&lt;br /&gt;  %d - Day of the month (01..31)&lt;br /&gt;  %H - Hour of the day, 24-hour clock (00..23)&lt;br /&gt;  %I - Hour of the day, 12-hour clock (01..12)&lt;br /&gt;  %j - Day of the year (001..366)&lt;br /&gt;  %m - Month of the year (01..12)&lt;br /&gt;  %M - Minute of the hour (00..59)&lt;br /&gt;  %p - Meridian indicator (``AM''  or  ``PM'')&lt;br /&gt;  %S - Second of the minute (00..60)&lt;br /&gt;  %U - Week  number  of the current year,&lt;br /&gt;          starting with the first Sunday as the first&lt;br /&gt;          day of the first week (00..53)&lt;br /&gt;  %W - Week  number  of the current year,&lt;br /&gt;          starting with the first Monday as the first&lt;br /&gt;          day of the first week (00..53)&lt;br /&gt;  %w - Day of the week (Sunday is 0, 0..6)&lt;br /&gt;  %x - Preferred representation for the date alone, no time&lt;br /&gt;  %X - Preferred representation for the time alone, no date&lt;br /&gt;  %y - Year without a century (00..99)&lt;br /&gt;  %Y - Year with century&lt;br /&gt;  %Z - Time zone name&lt;br /&gt;  %% - Literal ``%'' character&lt;br /&gt;&lt;br /&gt;   t = Time.now&lt;br /&gt;   t.strftime("Printed on %m/%d/%Y")   #=&gt; "Printed on 04/09/2003"&lt;br /&gt;   t.strftime("at %I:%M%p")            #=&gt; "at 08:56AM"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8072576307614958110?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8072576307614958110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8072576307614958110' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8072576307614958110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8072576307614958110'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/12/wywietlanie-daty.html' title='Wyświetlanie Daty'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3220263873914430354</id><published>2008-11-22T01:37:00.005+01:00</published><updated>2009-02-27T06:32:00.496+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>Netbeans 6.5, a GIT</title><content type='html'>W przypadku nowej wersji Netbeansa, szczególnie dla developerów Ruby on Rails uciążliwy może być brak wsparcia dla systemu wersjonowania GIT. Na szczęście dostępny jest już odpowiedni moduł (na razie w wersji eksperymentalnej), który doda do naszego środowiska odpowiednie wsparcie. Zainteresowanych odsyłam na &lt;a href="http://nbgit.org/"&gt;oficjalną stronę&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3220263873914430354?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3220263873914430354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3220263873914430354' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3220263873914430354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3220263873914430354'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/11/netbeans-65-git.html' title='Netbeans 6.5, a GIT'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4927607646294436812</id><published>2008-11-20T18:53:00.005+01:00</published><updated>2008-11-20T23:24:47.932+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>NetBeans 6.5</title><content type='html'>Właśnie ukazał się nowy &lt;a href="http://www.netbeans.org/downloads/index.html"&gt;NetBeans 6.5&lt;/a&gt;. Od dłuższego czasu używam tego środowiska do pisania aplikacji w Ruby on Rails i śmiało mogę go polecić wszystkim, którzy szykają edytora wspirającego w "rozsądny sposób podpowiadanie składni". Bardzo ciekawą cechą podpowiedzi kodu w NetBeansie jest wyświetlanie również odpowiedniego fragmentu RDoca, co umożliwia szybki dostęp do bardzo wielu przykładów użycia danych metod (bardzo cenne zwkłaszcza dla metod ActiveResource).&lt;br /&gt;&lt;br /&gt;Zainteresowanych odsyłam również na stronę &lt;a href="http://blog.huikau.com/2008/04/28/aloha-color-theme-for-netbeans-61/"&gt;Huukau&lt;/a&gt;, gdzie znajduje się bardzo dobry schemat graficzny dla developerów rubiego.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://pages.huikau.com/Aloha_ruby_61.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 537px; height: 383px;" src="http://pages.huikau.com/Aloha_ruby_61.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Alternatywny temat kolorystyczny znaleźć możemy również na stronie &lt;a href="http://blogs.sun.com/tor/date/20071008"&gt;Tora Norbyesa&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://blogs.sun.com/tor/resource/dark-pastels-ruby.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 647px; height: 568px;" src="http://blogs.sun.com/tor/resource/dark-pastels-ruby.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Na zakończenie ostatni ciekawy temat kolorystyczny, który znaleźć możemy na stronie &lt;a href="http://www.ibrasten.com/articles/2007/10/24/fadetogrey-netbeans-textmate-themes"&gt;iBrasten&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2327/1732727100_547cacc6de.jpg?v=0"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px; height: 344px;" src="http://farm3.static.flickr.com/2327/1732727100_547cacc6de.jpg?v=0" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4927607646294436812?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4927607646294436812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4927607646294436812' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4927607646294436812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4927607646294436812'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/11/netbeans-65.html' title='NetBeans 6.5'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4782695437036866836</id><published>2008-11-03T23:15:00.001+01:00</published><updated>2009-03-15T23:39:20.440+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu 8.10 Sun Java 1.6</title><content type='html'>Instalacja:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; sudo apt-get install sun-java6-jdk&lt;br /&gt; sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-6-sun/jre/bin/java 1100&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4782695437036866836?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4782695437036866836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4782695437036866836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4782695437036866836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4782695437036866836'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/11/ubuntu-810-sun-java-16.html' title='Ubuntu 8.10 Sun Java 1.6'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4840345456676350509</id><published>2008-11-03T21:00:00.003+01:00</published><updated>2009-03-15T23:39:11.795+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>RubyGems 1.3.1 na Ubuntu 8.10</title><content type='html'>Wraz z pojawieniem się nowej wersji Ubuntu 8.10 - nie obeszło się bez problemów. Domyślnie dla tej wersji apt-get instaluje rubygemy w wersji 1.2. Niestety polecenie:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo update_rubygems &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wydane po instalacji "gem install rubygems-update" się nie wywołuje.&lt;br /&gt;&lt;br /&gt;Oto metoda jak sobie z tym poradzić znaleziona na blogu (http://roninonrails.blogspot.com/2008/11/setting-up-ubuntu-810-for-ruby-on-rails.html):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz&lt;br /&gt;cd rubygems-1.3.1&lt;br /&gt;ruby setup.rb&lt;br /&gt;ln -s /usr/bin/gem1.8 /usr/bin/gem&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4840345456676350509?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4840345456676350509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4840345456676350509' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4840345456676350509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4840345456676350509'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/11/rubygems-131-na-ubuntu-810.html' title='RubyGems 1.3.1 na Ubuntu 8.10'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6031980237142977836</id><published>2008-10-16T03:10:00.004+02:00</published><updated>2009-02-27T06:28:51.003+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Ruby on Rails pod maską Ogólnopolskiej Informacji Medycznej</title><content type='html'>Firma &lt;a href="http://www.deltasoftware.pl"&gt;Delta Software&lt;/a&gt; oficjalnie uruchomiła serwis &lt;a href="http://www.informacja-medyczna.pl"&gt;Ogólnopolskiej Informacji Medycznej&lt;/a&gt;. Cały projekt zrealizowany został w technologii Ruby on Rails. Technologia ta umożliwiła wytworzenie produktu, który stać się ma największą konkurencją dla dotychczasowych portali medycznych. W chwili obecnej system działa w podstawowej funkcjonalności, jednakże bardzo szybko uruchamiane są dodatkowe moduły. W ostatecznej wersji serwis wykorzystywać będzie również algorytmy sztucznej inteligencji.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6031980237142977836?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6031980237142977836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6031980237142977836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6031980237142977836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6031980237142977836'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/10/ruby-on-rails-pod-mask-oglnopolskiej.html' title='Ruby on Rails pod maską Ogólnopolskiej Informacji Medycznej'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2014250576068974407</id><published>2008-07-10T02:58:00.010+02:00</published><updated>2009-02-27T06:29:17.966+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Instalacja Ruby on Rails 2.1 pod Ubuntu 8.04</title><content type='html'>Informacje zaczerpnięte są ze strony "&lt;a href="http://www.rubyhead.com/2008/04/25/installing-ruby-rails-on-ubuntu-804-hardy-heron/"&gt;Installing Ruby &amp; Rails on Ubuntu 8.04 Hardy Heron&lt;/a&gt;", ale jednocześnie starałem się je uzupełnić o rozwiązania problemów na jakie można trafić w trakcie instalacji (dodane elementy starałem się wyróżniać kolorem czerwonym).&lt;br /&gt;&lt;br /&gt;Krok 1:&lt;br /&gt;Instalacja pakietów podstawowych&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo apt-get install ruby irb ri rdoc ruby1.8-dev &lt;br/&gt;libzlib-ruby libyaml-ruby libreadline-ruby libncurses-ruby libcurses-ruby libruby &lt;br/&gt;libruby-extras libfcgi-ruby1.8 build-essential libopenssl-ruby libdbm-ruby libdbi-ruby &lt;br/&gt;libdbd-sqlite3-ruby sqlite3 libsqlite3-dev libsqlite3-ruby libxml-ruby libxml2-dev &lt;br/&gt;ruby &lt;span style="color:red;"&gt;rubygems&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:red;"&gt;Krok 2:&lt;/span&gt;&lt;br /&gt;Instalacja najnowszej wersji gem&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem update --system&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Może się zdażyć, że pojawi się komunikat następującej treści:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;uninitialized constant Gem::GemRunner&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Rozwiązanie można znaleźć na &lt;a href="http://ericbeland.com/2007/12/20/uninitialized-constant-gem-gemrunner"&gt;tej stronie&lt;/a&gt;, ale ponieważ jest krótkie pozwoliłem sobie je zamieścić poniżej:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gedit /usr/bin/gem&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A następnie przed linią:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Dodajemy:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'rubygems/gem_runner'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:red"&gt;3. Krok&lt;/span&gt;&lt;br /&gt;Dalsza aktualizacja gema:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;gem install rubygems-update&lt;br /&gt;sudo update_rubygems &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4. Krok&lt;br /&gt;Instalacja railsa&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem install rails&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To zainstaluje nam najnowszą wersję railsa. Gdybyśmy chcieli zainstalować również wcześniejszą wersję należy wywołać następującą komendę (zainstaluje ona railsa w wersji 2.0.2)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:red;"&gt;sudo gem install rails -v 2.0.2&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Krok&lt;br /&gt;Instalacja bazy danych i narzędzi pomocniczych&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo apt-get install mysql-server mysql-client libdbd-mysql-ruby &lt;span style="color:red;"&gt;mysql-query-browser mysql-admin&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:red;"&gt;6. Krok&lt;/span&gt;&lt;br /&gt;Instalacja gema mysql&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem install mysql&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W przypadku problemów z isntalacją warto przeczytać &lt;a href="http://mstanek.blogspot.com/2008/07/instalacja-gema-mysql-pod-ubuntu.html"&gt;tego posta&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:red;"&gt;6. Krok&lt;/span&gt;&lt;br /&gt;Instalacja dodatkowych przydatnych gemow:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem install mongrel sqlite3-ruby capistrano &lt;span style="color:red;"&gt;mini_magick mislav-will_paginate&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2014250576068974407?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2014250576068974407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2014250576068974407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2014250576068974407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2014250576068974407'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/07/instalacja-ruby-on-rails-21-pod-ubuntu.html' title='Instalacja Ruby on Rails 2.1 pod Ubuntu 8.04'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1567189379919572055</id><published>2008-07-08T15:12:00.006+02:00</published><updated>2009-02-27T06:23:58.572+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Instalacja gema mysql pod ubuntu</title><content type='html'>Jeżeli w czasie wywołania:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem install mysql &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pojawia się następujący błąd:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/usr/bin/ruby1.8 extconf.rb install mysql&lt;br /&gt;checking for mysql_query() in -lmysqlclient... no&lt;br /&gt;checking for main() in -lm... yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient... no&lt;br /&gt;checking for main() in -lz... yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient... no&lt;br /&gt;checking for main() in -lsocket... no&lt;br /&gt;checking for mysql_query() in -lmysqlclient... no&lt;br /&gt;checking for main() in -lnsl... yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient... no&lt;br /&gt;*** extconf.rb failed ***&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Należy zainstalować następującą bibliotekę:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo apt-get install libmysqlclient15-dev &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A następnie wywołać:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo gem install mysql &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1567189379919572055?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1567189379919572055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1567189379919572055' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1567189379919572055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1567189379919572055'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/07/instalacja-gema-mysql-pod-ubuntu.html' title='Instalacja gema mysql pod ubuntu'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8758924437278321383</id><published>2008-07-03T23:24:00.006+02:00</published><updated>2009-02-27T06:30:24.020+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Drag&amp;Drop dla drzewa</title><content type='html'>Jeżeli w projekcie nad którym pracujemy potrzebna jest funkcjonalność zapewniająca sortowanie listy możemy wykorzystać dwie rzeczy - &lt;a href="http://wiki.rubyonrails.org/rails/pages/HowToUseDragAndDropSorting"&gt;ScriptAculoUs(domyślnie dostarczona wraz z railsem) oraz ActsAsList&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Problem stanowiło natomiast utworzenie sortowalnego drzewa. Z pomocą w tym przypadku przychodzi rozwiązanie opracowane przez &lt;a href="http://www.artweb-design.de/2008/5/30/scriptaculous-sortabletree"&gt;Svena Fuchsa&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Poniżej przykładowe dwa dema:&lt;br /&gt;&lt;a href="http://files.artweb-design.de/javascript/scriptaculous-sortabletree/demo/bold.html"&gt;demo/bold.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://files.artweb-design.de/javascript/scriptaculous-sortabletree/demo/textmate.html"&gt;demo/textmate.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8758924437278321383?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8758924437278321383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8758924437278321383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8758924437278321383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8758924437278321383'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/07/drag-dla-drzewa.html' title='Drag&amp;Drop dla drzewa'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2236470518392996062</id><published>2008-06-27T13:14:00.007+02:00</published><updated>2009-02-27T06:11:03.670+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Migracje w rails 2.1</title><content type='html'>W nowym wydaniu Railsa w wersji 2.1 w nasze ręce oddana została poprawiona funkcjonalność związana z zarządzaniem migracjami. Poprawione zostały dwie rzeczy. Pierwsza dotyczy generowania samych migracji, które przestały być już oznaczane kolejnymi numerami wersji (stanowiło to czasami nie lada wyzwanie kiedy w projekcie kilka osób jednocześnie pracowało z modelem), a druga możliwości określania zmian w tabelach. &lt;br /&gt;&lt;br /&gt;Od wersji rails 2.1 migracje numerowane są tak zwanym stemplem czasowym. W praktyce oznacza to, że wygenerowanie migracji za pomocą &lt;span style="font-style:italic;"&gt;script/generate migration nowa_migracja&lt;/span&gt; spowoduje utworzenie pliku o nazwie zbliżonej do tej: 20080627102918_nowa_migracja.rb&lt;br /&gt;&lt;br /&gt;Wcześniej jeżeli dwie osoby jednocześnie wygenerowały migracje trzeba było cofać wprowadzone zmiany (najlepiej przed pobraniem zmian z SVNa - ponieważ tylko wtedy odbywało się to w miarę bezproblemowo), zmieniać nazwy plików i dopiero wówczas migrować model. Teraz proces ten przeprowadzany jest automatycznie. W momencie w którym &lt;span style="font-style:italic;"&gt;rake db:migrate&lt;/span&gt; stwierdzi, że w katalogu znajdują się migracje z wcześniejszym stemplem czasowym, cofa wszystkie zmiany, a następnie migruje model z uwzględnieniem wcześniejszej migracji. &lt;br /&gt;&lt;br /&gt;Druga zmiana w Railsie 2.1 dotyczy sposobu w jaki możemy definiować zmiany tabel przyjrzyjmy się poniższemu fragmentowi kodu:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;change_table :news do |:tabela| &lt;br /&gt;  tabela.belongs_to :issue # Doda kolumnę issue_id&lt;br /&gt;  tabela.string :naglowek, :autor # Doda dwie kolumny typu string&lt;br /&gt;  tabela.remove :header, :author #Usunie dwie kolumny&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Do dyspozycji mamy teraz następujace modyfikatory dostępne w bloku kodu metody change_table:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.index&lt;/span&gt; - dodaje indeks&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.change&lt;/span&gt; - zmienia definicję kolumny np. &lt;span style="font-style:italic;"&gt;tabela.change :nazwa, :string, :limit =&gt; 200&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.change_default&lt;/span&gt; - zmienia wartość domyślną dla kolumny&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.rename&lt;/span&gt; - zmienia nazwę kolumny&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.remove&lt;/span&gt; - usuwa kolumnę&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.remove_belongs_to&lt;/span&gt; - usuwa kolumnę z kluczem obcym&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;tabela.remove_timestams&lt;/span&gt; - stemple czasowe&lt;/li&gt;&lt;br /&gt;&lt;li&gt;dodatkowo możemy używać &lt;span style="font-style:italic;"&gt;(references, string, text, integer, float, decimal, datetime, timestamps, time, date, binary, boolean)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2236470518392996062?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2236470518392996062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2236470518392996062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2236470518392996062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2236470518392996062'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/migracje-w-rails-21.html' title='Migracje w rails 2.1'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2914771481256169439</id><published>2008-06-27T11:27:00.003+02:00</published><updated>2009-02-27T06:23:33.924+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Błąd: no such file to load -- mkmf</title><content type='html'>W przypadku kiedy chcemy zainstalować Mongrela, a pojawia się nam poniższy błąd:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Building native extensions.  This could take a while...&lt;br /&gt;ERROR:  Error installing mongrel:&lt;br /&gt; ERROR: Failed to build gem native extension.&lt;br /&gt;&lt;br /&gt;/usr/bin/ruby1.8 extconf.rb install mongrel&lt;br /&gt;extconf.rb:1:in `require': no such file to load -- mkmf (LoadError)&lt;br /&gt; from extconf.rb:1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;należy zainstalować developerską wersję ruby&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; sudo apt-get install ruby1.8-dev&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To powinno rozwiązać problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2914771481256169439?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2914771481256169439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2914771481256169439' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2914771481256169439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2914771481256169439'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/bd-extconfrb1.html' title='Błąd: no such file to load -- mkmf'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4508238264918462348</id><published>2008-06-27T11:07:00.004+02:00</published><updated>2009-02-27T06:24:05.577+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Problem z zależnościami rubygems w ubuntu 8.04</title><content type='html'>Korzystając z nowego railsa 2.1 w ubuntu 8.04 możemy natknąć się na następujący problem &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/locator.rb:91:in `add': wrong number of arguments (2 for 1) (ArgumentError)&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/locator.rb:91:in `plugins'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:63:in `locate_plugins'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:62:in `map'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:62:in `locate_plugins'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:27:in `all_plugins'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:22:in `plugins'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/plugin/loader.rb:45:in `add_plugin_load_paths'&lt;br /&gt; from /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:235:in `add_plugin_load_paths'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Występuje on w momencie kiedy dodamy do pliku konfiguracyjnego informację wiążącą naszą aplikację z konkretnymi gemami (i to o dziwo nie wszystkimi bo will_paginate działa prawidłowo) np.:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; config.gem 'mini_magick', :version =&gt; '~&gt;1.2.3'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Googlując za rozwiązaniem udało mi się znaleźć witrynę &lt;a href="http://rails.lighthouseapp.com/projects/8994/tickets/293-gem-dependencies-broken-in-2-1-0"&gt;http://rails.lighthouseapp.com/projects/8994/tickets/293-gem-dependencies-broken-in-2-1-0&lt;/a&gt;, gdzie z opisu w kolejnych postach można wywnioskować, że usunięcie pakietu &lt;span style="font-weight:bold;"&gt;rubygems&lt;/span&gt; i zainstalowanie go ze źródeł powinno pomóc. Niestety w moim przypadku nie dało to oczekiwanego rezultatu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4508238264918462348?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4508238264918462348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4508238264918462348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4508238264918462348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4508238264918462348'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/problem-z-zalenociami-rubygems-w-ubuntu.html' title='Problem z zależnościami rubygems w ubuntu 8.04'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4548393847355840764</id><published>2008-06-26T14:44:00.002+02:00</published><updated>2008-06-26T16:52:51.368+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Ściągawki dla programistów ruby on rails</title><content type='html'>Natknąłem się dzisiaj na bardzo ciekawy, a zarazem szeroki zbiór krótkich ściągawek dla programistów ruby on railsa. &lt;br /&gt;&lt;br /&gt;Warte polecenia:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://radarek.jogger.pl/2008/03/12/zestaw-ponad-40-sciagawek-dla-programistow-ruby-on-rails-i-n/"&gt;http://radarek.jogger.pl/2008/03/12/zestaw-ponad-40-sciagawek-dla-programistow-ruby-on-rails-i-n/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4548393847355840764?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4548393847355840764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4548393847355840764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4548393847355840764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4548393847355840764'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/cigawki-dla-programistw.html' title='Ściągawki dla programistów ruby on rails'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1058048960391554115</id><published>2008-06-26T13:51:00.010+02:00</published><updated>2009-02-27T06:29:26.692+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Paginacja w rails 2.1 (gem will_paginate)</title><content type='html'>W railsie 2.0.2 do paginacji można było używać will_paginate instalowanego jako plugin. Po przejściu do railsa 2.1 okazało się, że widoki zawierające paginatory przestały działać. Nie będę opisywał tutaj walki z usunięciem tego błędu - bo skutkowała wieloma mało zrozumiałymi komunikatami. &lt;br /&gt;&lt;br /&gt;Aby wykorzystać paginacje w railsie 2.1 należy:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;usunąć katalog will_paginate z /vendor/plugins/&lt;/li&gt;&lt;br /&gt;&lt;li&gt;do pliku environment.rb dodać nastepującą linijkę:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;config.gem 'mislav-will_paginate', &lt;br /&gt;    :version =&gt; '~&gt; 2.3.2', &lt;br /&gt;    :lib =&gt; 'will_paginate', &lt;br /&gt;    :source =&gt; 'http://gems.github.com'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Uwaga:na sieci znalazłem kilka wersji sposobu dodania will_paginate do environment.rb - niestety nie wszystie chciały działać!&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Na końcu pliku environment.rb należy dopisać (za słowem kluczowym &lt;span style="font-weight:bold;"&gt;end&lt;/span&gt;): &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;require 'will_paginate'&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;wywołać task raka: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo rake gems:install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Uwaga: instalacja gemów wymaga uprawnień administratora &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Teraz możemy cieszyć się prawidłowo działającą aplikacją.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1058048960391554115?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1058048960391554115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1058048960391554115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1058048960391554115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1058048960391554115'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/paginacja-w-rails-21-gem-willpaginate.html' title='Paginacja w rails 2.1 (gem will_paginate)'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4339523084011637549</id><published>2008-06-26T10:15:00.009+02:00</published><updated>2009-02-27T06:11:20.979+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Różnica pomiędzy count, length a size</title><content type='html'>W ruby on rails mamy do dyspozycji trzy metody określające ilość elementów w kolekcji - &lt;span style="font-weight:bold; font-style:italic;"&gt;length, count, size&lt;/span&gt;. Aby zoptymalizować działanie naszej aplikacji warto jednak wiedzieć w jaki sposób działa każda z nich:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;length&lt;/span&gt; &lt;span style="font-style:italic;"&gt;(np. obiekt.kolekcja.length)&lt;/span&gt; - pobiera całą kolekcje, a nastepnie zwraca liczbę elementów&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;count&lt;/span&gt; (np. obiekt.kolekcja.count) - zwraca liczbę elementów nie pobierając kolekcji do pamięci (wykorzystuje SQLową instrukcję count)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;size&lt;/span&gt; &lt;span style="font-style:italic;"&gt;(np. obiekt.kolekcja.size)&lt;/span&gt; - metoda ta jest połączeniem działania dwóch poprzednich metod. Jeżeli obiekt.kolekcja został wcześniej pobrany to działanie jest podobne do instrukcji &lt;span style="font-style:italic;"&gt;length&lt;/span&gt;, jeżeli natomiast kolekcja nie została pobrana wywołana zostanie instrukcja &lt;span style="font-style:italic;"&gt;count&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Mam nadzieję, że to krótkie wyjaśnienie pozwoli zrozumieć różnicę pomiędzy tymi trzema instrukcjami i jednocześnie pozwoli tworzyć bardziej efektywny kod.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4339523084011637549?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4339523084011637549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4339523084011637549' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4339523084011637549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4339523084011637549'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/rnica-pomidzy-count-length-size.html' title='Różnica pomiędzy count, length a size'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7757247139212500407</id><published>2008-06-24T16:06:00.007+02:00</published><updated>2009-04-14T20:27:39.294+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Ukryte Modele Markowa w rozpoznawaniu mowy</title><content type='html'>&lt;a title="View Ukryte modele Markowa jako metoda rozpoznawania mowy on Scribd" href="http://www.scribd.com/doc/14227406/Ukryte-modele-Markowa-jako-metoda-rozpoznawania-mowy" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Ukryte modele Markowa jako metoda rozpoznawania mowy&lt;/a&gt; &lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="doc_491869875311271" name="doc_491869875311271" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="100%" &gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=14227406&amp;access_key=key-1m8ngjuv5zimvgk5wthr&amp;page=1&amp;version=1&amp;viewMode="&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;        &lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=14227406&amp;access_key=key-1m8ngjuv5zimvgk5wthr&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_491869875311271_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;div style="margin: 6px auto 3px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;"&gt;    &lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/Research/" style="text-decoration: underline;"&gt;Research&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/ukryte%20%C5%82a%C5%84cuchy%20markowa" style="text-decoration: underline;"&gt;ukryte łańcuchy mark&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/%C5%82a%C5%84cuchy%20markowa" style="text-decoration: underline;"&gt;łańcuchy markowa&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7757247139212500407?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7757247139212500407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7757247139212500407' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7757247139212500407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7757247139212500407'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/ukryte-modele-markowa-w-rozpoznawaniu.html' title='Ukryte Modele Markowa w rozpoznawaniu mowy'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-5162674127620200824</id><published>2008-06-24T15:09:00.004+02:00</published><updated>2008-06-24T15:25:45.431+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sztuczna inteligencja'/><title type='text'>Programowanie gier, modyfikacje alfa-beta obcięcia oraz heurystyki funkcji oceniających.</title><content type='html'>&lt;br/&gt;&lt;br /&gt;Pełna wersja dokumentu dostępna pod adresem: &lt;a href="http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Sztuczna_inteligencja_w_grach.pdf"&gt;http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Sztuczna_inteligencja_w_grach.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Wstęp&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Gwałtowny rozwój komputerów w drugiej połowie ubiegłego wieku przyczynił się do znacznego postępu zarówno w nauce jak i przemyśle. Dały one możliwość realizacji rzeczy które wcześniej można było analizować jedynie teoretycznie. W głowie nie jednego naukowca zrodziło się wówczas pytanie, czy maszyna będzie w stanie dorównać kiedyś możliwością człowieka?&lt;br /&gt;Zaczęła rozwijać się dynamicznie dziedzina zwana sztuczną inteligencją. Zadawano sobie pytanie w jaki sposób mierzyć zdolności maszyny? Dylemat ten rozwiązał Alan Turing konstruując słynny test Turinga. Test ten odnosi się jednak tylko do zdolności językowych. Sam Alan Turing a nawet Shannon rozważał rozszerzenie tego testu o przeprowadzenie rozgrywki w szachy, od wieków bowiem gra ta była uznawana za królową wszystkich gier. Turing stwierdził nawet w jednej ze swoich wypowiedzi z 1951 roku, że nikt nie jest w stanie napisać programu, który gra lepiej od niego samego. Mimo niezaprzeczalnie wielkiego geniuszu w tej kwestii się pomylił. &lt;br /&gt;&lt;br /&gt;Mimo że nie ujęta w teście Turinga gra w szachy przez wielu uważana była za wyznacznik zdolności maszyny do myślenia. Określała granicę pomiędzy możliwościami ludzkiego umysłu a maszyną. Ostatecznie po 45 latach prób, zaczynając od roku 1952, kiedy to powstał pierwszy program A. Sammuela,  maszyna pokonała szachowego mistrza świata.   &lt;br /&gt;&lt;br /&gt;Nie tylko szachy wzbudzały zainteresowanie uczonych. Badania i eksperymenty  prowadzone były dla bardzo wielu popularnych gier, wśród nich othello, go warcaby. W wielu z nich ostateczny sukces, to znaczy zwycięstwo nad człowiekiem został osiągnięty dużo wcześniej niż w szachach. Przykładowo problem gry w warcaby uważa się obecnie za praktycznie rozstrzygnięty. Oznacza to, że w zdecydowanej większości przypadków jesteśmy w stanie określić wynik gry już po wykonaniu kilku pierwszych ruchów. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Gra, strategia i drzewo gry&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Według definicji Von Noumana i Morgensterna gra to składa się z zestawu reguł określających możliwości wyboru postępowania jednostek znajdujących się w sytuacji określanej mianem konfliktu interesów. Każda z tych jednostek stara się maksymalizować swój własny zysk i jednocześnie zminimalizować zysk pozostałych graczy. Reguły gry określają też ilość informacji dostępną każdemu z graczy oraz wysokość wygranych i przegranych.&lt;br /&gt;&lt;br /&gt;W ogólności grę można rozumieć jako rozgrywkę prowadzoną przez gracza lub graczy, zgodnie z ustalonymi zasadami gry, w celu osiągnięcia ściśle zdefiniowanego celu. &lt;br /&gt;&lt;br /&gt;Należałoby również zdefiniować pojęcie równie ważne - strategia gry, pod którym rozumieć będziemy kompletny zbiór zasad, które determinują posunięcia gracza, wybierane zależnie od sytuacji powstających podczas gry. &lt;br /&gt;&lt;br /&gt;Gry można podzielić również na kilka kategorii w zależności od charakterystycznych cech.&lt;br /&gt;&lt;br /&gt;Ze względu na ilość graczy:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Gry bezosobowe (np. Gra w życie)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Gry jednoosobowe (puzzle, pasjans)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Gry dwuosobowe (szachy, warcaby, otello, go)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Gry wieloosobowe (poker, brydż)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Wygrana i przegrana:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Gry o sumie zerowej (wygrana jednego gracza oznacza przegraną drugiego gracza) – szachy, warcaby, otello&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Gry o sumie nie zerowej – np. Dylemat więźnia&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Współpraca graczy:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Kooperacyjne (gracze współpracują ze sobą)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Niekooperacyjne (gracze nie współpracują ze sobą)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Występowanie w grze elementu losowości:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;ałkowicie losowe (ruletka)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Częściowo losowe (brydż i inne gry karciane)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Całkowicie deterministyczne (warcaby, szachy, otello, go)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;To czym jest gra można wyrazić również pewnym równaniem:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Gra = cel + stan początkowy + operatory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gdzie pod pojęciem operatora rozumieć możemy stosowanie reguł gry. Działanie operatora nie musi być deterministyczne – może go określać np. rozkład zmiennej losowej, w grach częściowo losowych takich np. brydż. Każdy operator może posiadać również koszt związany z jego zastosowaniem. Należy podkreślić, że w grze dwuosobowej mamy wpływ na wybór tylko połowy operatorów. &lt;br /&gt;Rozpoczęcie gry ze stanu początkowego, a następnie stosowanie możliwych operatorów prowadzi do zbudowania tak zwanego drzewa gry, którego reprezentacja przedstawiona jest na rysunku 1(rysunek dostępny w dokumencie pdf).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Algorytm Min-Max&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Jednym z większych osiągnięć w teorii gier było opracowanie algorytmu min-max[KNU75]. Zasada jego działania opiera się na prostym spostrzeżeniu, że podczas gry każda ze stron stara się maksymalizować swoje zyski, przy jednoczesnej minimalizacji zysków przeciwnika1(podejście takie można zauważyć już w definicji Von Noumana i Morgensterna). &lt;br /&gt;&lt;br /&gt;Zakładając że możemy oszacować stan gry w każdym momencie z dość dużym przybliżeniem, jesteśmy w stanie przewidzieć, które ruchy przybliżą nas do wygranej, a które nie. Oczywiście im głębiej będziemy analizować drzewo gry, tym lepiej można wybrać operatory, które prowadzą nas do wygranej. W ekstremalnym przypadku, gdy jesteśmy w stanie rozwinąć całe drzewo gry jednoznacznie możemy wybrać posunięcia prowadzące nas do wygranej. Algorytm min-max został opracowany i opublikowany przez Knutha i Moore'a w 1975 r. Stanowi on fundament działania wielu innych algorytmów. Ilustracja działania algorytmu min-max przedstawiona jest na rysunku 2 (dostępny w wersji pdf dokumentu).&lt;br /&gt;&lt;br /&gt;Na jakość gry przy wykorzystaniu algorytmu min-max wpływają z jednej strony głębokość przeszukiwania z drugiej jakość funkcji heurystycznej. Nie da się osiągnąć zadowalających wyników jeżeli którykolwiek z tych elementów jest źle dobrany. &lt;br /&gt;&lt;br /&gt;Algorytm min-max przyczynił się do powstania algorytmu alfa-beta obcięcia, którego działanie polega na ograniczeniu ilości rozwijanych wierzchołków drzewa gry. Dokładne opisy algorytmu Alfa-Beta obcięcia można znaleźć w pracy [KWA04]. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Konstrukcja funkcji heurystycznej&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Jak wspomniano we wcześniejszym rozdziale na jakość działania algorytmy alfa-beta obcięcia zasadniczy wpływ ma stworzenie odpowiedniej funkcji oceniającej. Funkcja oceniająca jest funkcją heurystyczną1, to znaczy konstruowaną w założeniu, że pewne stany gry są lepsze lub gorsze od innych. Funkcja heurystyczna zazwyczaj przyjmuje postać wielomianu postaci:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;F(s) = w1 * x1 + ... + wn * xn,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;gdzie:&lt;br /&gt;s - to pewien stan gry, który chcemy ocenić, &lt;br /&gt;x1 - do xn to pewne cechy (np. ilość pionków na planszy, zajmowanie pewnych pól szachownicy),&lt;br /&gt;w1 - do wn są wagami z jakimi brana jest pod uwagę wartość pewnej cechy.&lt;br /&gt;&lt;br /&gt;Konstrukcja funkcji heurystycznej, to znaczy dobór odpowiednich parametrów oraz ich wag, zależy zazwyczaj od projektanta (programisty). Z jednej strony podejście takie jest dobre, ponieważ pozwala podzielić problem na dwa mniejsze:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;wyboru cech branych pod uwagę,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;doboru wagi każdej z wcześniej wybranych cech.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Z drugiej natomiast pozostawia pewien element subiektywności osobie, która konstruuje taką funkcję. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;GLEM – ogólny liniowy model oceniania&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;W odpowiedzi na problemy związane z konstrukcją heurystycznych funkcji oceniających powstał GLEM (Generalized Linear Evaluation Model). Ideą jaka przyświecała jego powstaniu była chęć stworzenia standardowego sposobu rozwiązywania klasy problemów cechujących się tym, że funkcję heurystyczną można przedstawić jako kombinację liniową dostatecznej ilości cech [BURO02]. GLEM nie zwalnia nas co prawda z obowiązku wyboru cech podstawowych, przez autorów artykułu nazwanych atomowymi. Nadal zmuszeni jesteśmy określić jakie elementy mają być brane pod uwagę. Przez cechy atomowe rozumiemy tutaj na przykład cechy takie jak obecność konkretnego pionka na konkretnym polu planszy, posiadanie konkretnej karty itp. Resztę parametrów to znaczy wartości wag z jakimi cechy te będą brane pod uwagę dobierane są przez algorytm automatycznie na podstawie dostarczonych przykładów uczących. &lt;br /&gt;&lt;br /&gt;.... dalsza część artykułu dostępna w&lt;a href="http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Sztuczna_inteligencja_w_grach.pdf"&gt; wersji PDF &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-5162674127620200824?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/5162674127620200824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=5162674127620200824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/5162674127620200824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/5162674127620200824'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/programowanie-gier-modyfikacje-alfa.html' title='Programowanie gier, modyfikacje alfa-beta obcięcia oraz heurystyki funkcji oceniających.'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1215190753075844274</id><published>2008-06-24T14:01:00.042+02:00</published><updated>2009-02-27T06:12:58.972+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Inżynieria Oprogramowania'/><title type='text'>Wzorce projektowe warsty prezentacji</title><content type='html'>&lt;br/&gt;&lt;br /&gt;Dokument w wersji PDF można pobrać z tego miejsca &lt;a href="http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Wzorce_Projektowe.pdf"&gt;http://www.deltasoftware.pl/dokumenty/Michal_Stanek-Wzorce_Projektowe.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Wstęp&lt;/h2&gt;&lt;br /&gt;Wzorce projektowe są ogólnymi rozwiązaniami popularnych problemów, jakie pojawiają się podczas projektowania systemów informatycznych. Użycie przetestowanych i efektywnych rozwiązań pozwala zminimalizować koszty oraz skrócić czas potrzebny do wytworzenia oprogramowania. Polepszeniu ulega także komunikacja między ekspertami i zespołami projektowymi.&lt;br /&gt;&lt;br /&gt;Dokument ten omawia wzorce projektowe warstwy prezentacji, na przykładzie platformy J2EE. Po wstępnym omówieniu problemów związanych z tworzeniem nowoczesnych aplikacji biznesu elektronicznego, przedstawione zostały trzy wzorce projektowe warstwy prezentacji: Intercepting Filter, Context Object, Composite View. Każdy wzorzec został ogólnie omówiony, przedstawiono  diagramy klas oraz sekwencji, przedstawiono również przykładowe strategie implementacji. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Projektowanie aplikacji J2EE&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Specyfikacja J2EE powstała z myślą o zaspokojeniu potrzeb developerów aplikacji biznesu elektronicznego. Zawiera ona takie składowe jak strony JSP, komponenty JSP, usługi nazw jak JNDI, i wiele innych. Każdy z tych składników w mniejszym lub większym stopniu zaspokaja potrzeby &lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;EJB -  Reprezentuje komponent Enterprise Java Bean, związany jest z reguły z obiektem biznesowym. Rolę tę pełni zazwyczaj komponent sesyjny lub Entity.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;JSP - Java Server Pages. Technologia związana z generowanie widoku za pomocą osadzenia kody Javy na stronie HTML. Kod Javy zawarty jest w specjalnych znacznikach, a sama strona JSP wykonywana jest przez serwer servletów.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Trzeba zdawać sobie sprawę z tego, że wiele, a można byłoby zaryzykować twierdzenie, że większość dzisiejszych aplikacji biznesu elektronicznego wykorzystuje możliwości, jakie dają sieci komputerowe. Projektanci stają wobec tego przed zupełnie nowymi wyzwaniami, wśród których wyróżnić można aspekt związany z rozproszeniem, dostępnością, bezpieczeństwem itp. Tym własnie wyzwanią stawiają czoła wzorce projektowe opracowane dla platformy &lt;span style="font-style:italic;"&gt;J2EE&lt;/span&gt; przez konsorcjum Sun Java Center. Niniejszy dokument skupi sie na omówieniu trzech wzorców warstwy prezentacji. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Wzorce projektowe w J2EE&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Wzorce projektowe&lt;/span&gt; są ogólnymi rozwiązaniami popularnych problemów, jakie pojawiają się podczas projektowania systemów informatycznych. Użycie przetestowanych i efektywnych rozwiązań pozwala w efekcie uzyskać lepsze rozwiązania charakteryzujące się miedzy innymi: &lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Poprawionym aspektem przyszłej pielęgnacji aplikacji.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lepszą modułowością.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Możliwością rozdzielenia ról członków zespołu projektowo-programistycznego.&lt;/li&gt;&lt;br /&gt;Wielokrotnym wykorzystaniem komponentów.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Poprawieniem bezpieczeństwa dostępu.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Redukcją intensywności komunikacji sieciowej.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Zminimalizowanym kosztem wytworzenia.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Podczas projektowania systemów J2EE, często napotykamy podobne problemy. Warto przyjrzeć się kilku z nim, aby zrozumieć jak wielką rolę odgrywają dzisiaj wzorce projektowe. &lt;br /&gt;&lt;br /&gt;Często zdarza się, że niedoświadczony programista zawiera na stronie JSP kod odpowiedzialny za wygląd (HTML), logikę biznesową(Java) oraz dostęp do bazy danych(SQL). Wprowadzenie modułu sterującego pozwoliłoby uzyskać rozwiązanie zdecydowanie lepsze. Poprawiona zostałaby modułowość, jak również przyszła możliwość modyfikacji tak utworzonego kodu. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDkASOV6FI/AAAAAAAAEPE/oa6Ql6ooReo/s1600-h/Praktyki(ModulSterujacy).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDkASOV6FI/AAAAAAAAEPE/oa6Ql6ooReo/s400/Praktyki(ModulSterujacy).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215419062038161490"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Równie istotnym zagadnieniem jest wydzielenie kodu odpowiedzialnego za logikę biznesową z elementu odpowiedzialnego za przygotowanie widoku. Ponieważ strony JSP pozwalają umieszczać w ich wnętrzu kod Javy, programiści bardzo często umieszczają w nich typowe akcje związane z logiką biznesową. Są one niezależne i niezwiązane z formą ich prezentacji i powinny zostać wydzielone do oddzielnych klas np. Enterprise JavaBeans.&lt;br /&gt;&lt;br /&gt;Podobnym problemem związanym ze stronami JSP, jest umieszczenie w nich kodu odpowiedzialnego za przygotowanie oraz konwersję danych. Stwarza to kłopoty związane z redundancją kodu. Rozwiązaniem tego problemu, tak jak poprzednio jest wydzielenie kodu konwersji do oddzielnych klas. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDkPmJRCHI/AAAAAAAAEPM/VPmA6n5BoN8/s1600-h/Praktyki(podzial).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDkPmJRCHI/AAAAAAAAEPM/VPmA6n5BoN8/s400/Praktyki(podzial).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215419325083617394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Programiści aplikacji internetowych napotykają również często na dwa inne problemy. Pierwszy z nich związany jest z odpowiednim ukrywaniem zasobów przed klientem, który najpierw powinien spełnić pewne warunki, np. przejść poprawnie proces logowania do systemu. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDkcA8z2jI/AAAAAAAAEPU/yKr3vP1kyKo/s1600-h/Praktyki(dostep).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDkcA8z2jI/AAAAAAAAEPU/yKr3vP1kyKo/s400/Praktyki(dostep).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215419538437560882" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Drugi problem związany jest ze specyfikacją protokołu &lt;span style="font-weight:bold;"&gt;http&lt;/span&gt;, a dokładniej ze sposobem komunikacji przeglądarki z serwerem. Często zdarza się, że żądanie wykonania pewnej akcji zostaje powielone. W przypadku kiedy taka akcja powoduje modyfikacje danych, należy wyeliminować takie żądanie. Rozwiązaniem tych problemów może być wprowadzenie modułu sterującego takiego jak &lt;span style="font-weight:bold;"&gt;front controller&lt;/span&gt; [ALUR2004].&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDksADXOhI/AAAAAAAAEPc/y9cWgEddUMk/s1600-h/Praktyki(token).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDksADXOhI/AAAAAAAAEPc/y9cWgEddUMk/s400/Praktyki(token).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215419813074516498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Doświadczony programista zdaje sobie również sprawę z faktu, że uzależnienie aplikacji od protokołu, w jakim pracuje, znacznie ogranicza jej późniejszy rozwój. W obecnych czasach, wraz z bardzo dynamicznych rozwojem urządzeń mobilnych jest to szczególnie istotne, aby aplikacja mogła pracować w wielu różnych środowiskach, a komunikacja z nią byłą możliwa za pomocą dowolnej ilości protokołów. Wzorzec projektowy o nazwie &lt;span style="font-weight:bold;"&gt;Context Object&lt;/span&gt;, stanowi rozwiązanie tego problemu.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDlUlnXlbI/AAAAAAAAEPk/4zMtjgYVNac/s1600-h/Praktyki(niezaleznosc).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDlUlnXlbI/AAAAAAAAEPk/4zMtjgYVNac/s400/Praktyki(niezaleznosc).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215420510352414130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Jest to tylko kilka problemów, z jakimi możemy spotkać się projektując aplikację sieci WWW pracującą nie tylko w technologii &lt;span style="font-weight:bold;"&gt;J2EE&lt;/span&gt;. Warto zaznajomić się jednak ze wszystkimi wzorcami projektowymi, gdyż wielu przypadkach nie musimy wynajdywać tak zwanego "koła" od nowa, a wypracowane przez społeczność programistów rozwiązania wielokrotnie zaspokajają wszystkie nasze potrzeby. W kolejnej części tego dokumentu omówię dokładniej trzy spośród wielu istniejących wzorców. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Wzorce projektowe J2EE warstwy prezentacji&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Intercepting Filter&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Często możemy spotkać się z sytuacją, w której przed przystąpieniem do właściwego przetwarzania żądania strony JSP, musimy wstępnie przetworzyć dane. Operacja ta może być przykładowo związana z przetworzeniem kodowania parametrów żądania klienta. Nie trudno sobie wyobrazić, że taka konwersja musi się pojawić na każdej stronie, która w jakikolwiek sposób wykorzystuje parametry żądania klienta. Interesuje nas wobec tego rozwiązanie, którego nie będzie trzeba integrować z głównym przetwarzaniem. Wzorzec &lt;span style="font-weight:bold;"&gt;Intercepting Filter&lt;/span&gt; powinniśmy stosować właśnie wtedy, gdy chcemy przechwycić i modyfikować żądanie i odpowiedź przed i po właściwym przetwarzaniu. Ogólny schemat ideowy tego rozwiązania znajduje się na poniższym rysunku:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDmq38rhQI/AAAAAAAAEPs/AxTbS4WGrjE/s1600-h/InterceptingFilter(idea_dzialania).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDmq38rhQI/AAAAAAAAEPs/AxTbS4WGrjE/s400/InterceptingFilter(idea_dzialania).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215421992742388994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Intercepting Filter najczęściej stosowany jest do:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Sprawdzenie, czy z klientem związana jest poprawna sesja.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sprawdzenie, czy obsługiwany jest dany rodzaj przeglądarki.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sprawdzenie, jakiego kodowania używa klient do wysyłania danych oraz konwersja tych danych.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Deszyfrowanie lub dekompresja strumienia danych.Sprawdzenie, czy z klientem związana jest poprawna sesja.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sprawdzenie, czy obsługiwany jest dany rodzaj przeglądarki.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sprawdzenie, jakiego kodowania używa klient do wysyłania danych oraz konwersja tych danych.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Deszyfrowanie lub dekompresja strumienia danych.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Typowym rozwiązaniem tego typu problemów jest umieszczenie szeregu zagnieżdżonych instrukcji &lt;span style="font-weight:bold;"&gt;if-then-else&lt;/span&gt;. Ponieważ jednak kod taki trzeba umieścić w każdym elemencie naszej aplikacji uzyskujemy bardzo dużą redundancję kodu. Naszym celem jest więc zastosowanie rozwiązania charakteryzującego się następującymi właściwościami.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Będzie stanowić scentralizowane, wspólne przetwarzanie dla wszystkich żądań (np. sprawdzanie kodowania).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Nie będzie mocno związane z kodem przetwarzania zasadniczego. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Będzie umożliwiać stosowanie niezależnych komponentów, które w łątwy sposób mogą być dodawane przed lub po zasadniczym przetwarzaniu.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Na dwóch poniższych rysunkach przedstawione zostały diagramy klas oraz diagramy sekwencji wzorca &lt;span style="font-weight:bold;"&gt;Intercepting Filter&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDnzZERNsI/AAAAAAAAEP0/Ud7f7hD0VuI/s1600-h/InterceptingFilter(diagram_klas).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDnzZERNsI/AAAAAAAAEP0/Ud7f7hD0VuI/s400/InterceptingFilter(diagram_klas).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215423238583170754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDn5un3WDI/AAAAAAAAEP8/m4m4QJTzND4/s1600-h/InterceptingFilter(diagram_sekwencji).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDn5un3WDI/AAAAAAAAEP8/m4m4QJTzND4/s400/InterceptingFilter(diagram_sekwencji).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215423347448830002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Opis poszczególnych elementów wzorca:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;FilterManager&lt;/span&gt; - jest menadżerem filtrów. Jego zadaniem jest tworzenie obiektu FilterChain oraz ustawienie odpowiedniej sekwencji wywoływanych filtrów. FilterManager może być konfigurowalny za pomocą zewnętrznego pliku konfiguracyjnego, który określa w jakiej kolejności i jakie filtry zostaną wywołane.&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;FilterChain&lt;/span&gt; - stanowi uporządkowany zbiór niezależnych od siebie filtrów. FilterChain odpowiedzialny jest również za koordynowanie wywołań poszczególnych filtrów. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Filter&lt;/span&gt; - reprezentuje niezależny filtr. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Target&lt;/span&gt; - stanowi zasób żądania. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Najczęstszą implementacją wzorca &lt;span style="font-weight:bold;"&gt;Intercepting Filter&lt;/span&gt; jest wykorzystanie strategii filtru standardowego [ALUR2004]. Strategia ta zakłada wykorzystanie standardowego mechanizmu tworzenia łańcuchów filtrów, zdefiniowanego w specyfikacji serwletów w wersji 2.3. Filtry tak utworzone bazują na standardowym interfejsie &lt;span style="font-style:italic;"&gt;javax.servlet.Filter&lt;/span&gt; i są luźno powiązane ze sobą oraz docelowymi zasobami. Kontrola tak utworzonych filtrów odbywa się w sposób deklaratywny, za pomocą deskryptora wdrożenia. &lt;br /&gt;&lt;br /&gt;Zastosowanie takiego podejścia pozawala nam uzyskać rozwiązanie uniwersalne, w którym każdy filtr stanowi niezależny komponent. W przyszłości istnieje możliwość ponownego wykorzystania tak przygotowanych filtrów, lub też użycia filtrów dostarczonych przez innych. Deklaratywny sposób zarządzania filtrami za pomocą deskryptora wdrożenia umożliwia napisanie aplikacji, która nieświadoma jest obecności filtrów. W żaden sposób nie są one, ani zarządzanie nimi związane z zasadniczym kodem przetwarzania. Jako przykład takiego rozwiązania przedstawię filtr, zajmujący się konwersją kodowania różnego rodzaju kodowań formularzy stron WWW. Przedstawiany kod będzie przykładem wykorzystania wzorca &lt;span style="font-style:italic;"&gt;Intercepting Filter&lt;/span&gt; do implementacji wzorca o nazwie &lt;span style="font-style:italic;"&gt;Łańcuch odpowiedzialności&lt;/span&gt;. Struktura klas przykładu przedstawiona jest na poniższym rysunku.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDoztYoLYI/AAAAAAAAEQE/-oc69UW1bWA/s1600-h/InterceptingFilter(strategia_filtru).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDoztYoLYI/AAAAAAAAEQE/-oc69UW1bWA/s400/InterceptingFilter(strategia_filtru).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215424343548898690" /&gt;Interceptring Filter - strategia filtru standardowego&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Klasa bazowa implementująca podstawowe metody klasy Filter, z niej będą dziedziczyć klasy &lt;span style="font-weight:bold;"&gt;StandardEncodeFilter&lt;/span&gt; - zajmująca się przetwarzaniem formularzy standardowych &lt;span style="font-style:italic;"&gt;(application/x-www-form-urlencoded)&lt;/span&gt; oraz klasa &lt;span style="font-weight:bold;"&gt;MultipartEncodeFilter&lt;/span&gt; - zajmująca się przetwarzaniem formularzy umożliwiających wysyłanie plików&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class BaseEncodeFilter implements javax.servlet.Filter {&lt;br /&gt;&lt;br /&gt;  private javax.servlet.FilterConfig myFilterConfig;&lt;br /&gt;  public void doFilter(javax.servlet.ServletRequest servletRequest, &lt;br /&gt;                       javax.servlet.ServletResponse servletResponse,&lt;br /&gt;                       javax.servlet.FilterChain filterChain) &lt;br /&gt;                       throws java.io.IOException,&lt;br /&gt;                       javax.servlet.ServletException {&lt;br /&gt;    filterChain.doFilter(servletRequest, servletResponse);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;  public javax.servlet.FilterConfig getFilterConfig() {&lt;br /&gt;    return myFilterConfig; &lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  public void destroy() { }&lt;br /&gt;&lt;br /&gt;  public void init(javax.servlet.FilterConfig filterConfig)&lt;br /&gt;                   throws javax.servlet.ServletException { &lt;br /&gt;    myFilterConfig = filterConfig;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Klasa odpowiedzialna za przetwarzanie formularzy standardowych: &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class StandardEncodeFilter extends BaseEncodeFilter {&lt;br /&gt;// Tworzy nowy StandardEncodeFilter&lt;br /&gt;  public StandardEncodeFilter()   {  }&lt;br /&gt;&lt;br /&gt;  public void doFilter(javax.servlet.ServletRequest servletRequest,&lt;br /&gt;                       javax.servlet.ServletResponse servletResponse,&lt;br /&gt;                       javax.servlet.FilterChain filterChain) &lt;br /&gt;                       throws java.io.IOException, &lt;br /&gt;                       javax.servlet.ServletException {&lt;br /&gt;&lt;br /&gt;    String contentType = servletRequest.getContentType();&lt;br /&gt;    if ((contentType == null) || contentType.equalsIgnoreCase(&lt;br /&gt;      "application/x-www-form-urlencoded")) {&lt;br /&gt;      translateParamsToAttributes(servletRequest, servletResponse);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    filterChain.doFilter(servletRequest, servletResponse);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void translateParamsToAttributes(ServletRequest request,&lt;br /&gt;                                           ServletResponse response) {&lt;br /&gt;    Enumeration paramNames = request.getParameterNames();&lt;br /&gt;&lt;br /&gt;    while (paramNames.hasMoreElements())     {&lt;br /&gt;      String paramName = (String) paramNames.nextElement();&lt;br /&gt;      String [] values;&lt;br /&gt;      values = request.getParameterValues(paramName);&lt;br /&gt;      if (values.length == 1)&lt;br /&gt;        request.setAttribute(paramName, values[0]);&lt;br /&gt;      else&lt;br /&gt;        request.setAttribute(paramName, values);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Klasa odpowiedzialna za przetwarzanie formularzy umożliwiających wysyłanie plików:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MultipartEncodeFilter extends BaseEncodeFilter {&lt;br /&gt;  public MultipartEncodeFilter() { }&lt;br /&gt;  public void doFilter(javax.servlet.ServletRequest servletRequest,&lt;br /&gt;                       javax.servlet.ServletResponse servletResponse,&lt;br /&gt;                       javax.servlet.FilterChain filterChain)&lt;br /&gt;                       throws java.io.IOException, &lt;br /&gt;                       javax.servlet.ServletException {&lt;br /&gt;    String contentType = servletRequest.getContentType();   &lt;br /&gt;    // Stosujemy filtr tylko dla kodowania wieloczęściowego &lt;br /&gt;   if (contentType.startsWith("multipart/form-data")){&lt;br /&gt;     try {&lt;br /&gt;       String uploadFolder = getFilterConfig().getInitParameter("UploadFolder");&lt;br /&gt;       if (uploadFolder == null) uploadFolder = ".";&lt;br /&gt;       &lt;br /&gt;       MultipartRequest multi = new MultipartRequest(servletRequest, &lt;br /&gt;                                     uploadFolder,1 * 1024 * 1024 );&lt;br /&gt;       Enumeration params = multi.getParameterNames();&lt;br /&gt;       while (params.hasMoreElements()) {&lt;br /&gt;         String name = (String)params.nextElement();&lt;br /&gt;         String value = multi.getParameter(name);&lt;br /&gt;         servletRequest.setAttribute(name, value);&lt;br /&gt;       }&lt;br /&gt;       Enumeration files = multi.getFileNames();&lt;br /&gt;       while (files.hasMoreElements()) {&lt;br /&gt;         String name = (String)files.nextElement();&lt;br /&gt;         String filename = multi.getFilesystemName(name);&lt;br /&gt;         String type = multi.getContentType(name);&lt;br /&gt;         File f = multi.getFile(name);&lt;br /&gt;         // W tym miejscu w razie konieczności wykonujemy coś na pliku&lt;br /&gt;       }&lt;br /&gt;     } catch (IOException e) {&lt;br /&gt;       LogManager.logMessage("błąd odczytu lub zapisu pliku "+ e);&lt;br /&gt;     }&lt;br /&gt;   } // koniec if&lt;br /&gt;   filterChain.doFilter(servletRequest, servletResponse);&lt;br /&gt;  } // koniec metody doFilter()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Deskryptor wdrożenia konfigurujący zestaw filtrów:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;filter&gt;&lt;br /&gt;  &lt;filter-name&gt;StandardEncodeFilter&lt;/filter-name&gt;&lt;br /&gt;  &lt;display-name&gt;StandardEncodeFilter&lt;/display-name&gt;&lt;br /&gt;  &lt;description&gt;&lt;/description&gt;&lt;br /&gt;  &lt;filter-class&gt; encodefilter.StandardEncodeFilter&lt;/filter-class&gt;&lt;br /&gt;&lt;/filter&gt;&lt;br /&gt;&lt;br /&gt;&lt;filter&gt;&lt;br /&gt;  &lt;filter-name&gt;MultipartEncodeFilter&lt;/filter-name&gt;&lt;br /&gt;  &lt;display-name&gt;MultipartEncodeFilter&lt;/display-name&gt;&lt;br /&gt;  &lt;description&gt;&lt;/description&gt;&lt;br /&gt;  &lt;filter-class&gt;encodefilter.MultipartEncodeFilter&lt;/filter-class&gt;&lt;br /&gt;  &lt;init-param&gt;&lt;br /&gt;    &lt;param-name&gt;UploadFolder&lt;/param-name&gt;&lt;br /&gt;    &lt;param-value&gt;/home/files&lt;/param-value&gt;&lt;br /&gt;  &lt;/init-param&gt;&lt;br /&gt;&lt;/filter&gt;&lt;br /&gt;&lt;br /&gt;&lt;filter-mapping&gt;&lt;br /&gt;  &lt;filter-name&gt;StandardEncodeFilter&lt;/filter-name&gt;&lt;br /&gt;  &lt;url-pattern&gt;/EncodeTestServlet&lt;/url-pattern&gt;&lt;br /&gt;&lt;/filter-mapping&gt;&lt;br /&gt;&lt;filter-mapping&gt;&lt;br /&gt;  &lt;filter-name&gt;MultipartEncodeFilter&lt;/filter-name&gt;&lt;br /&gt;  &lt;url-pattern&gt;/EncodeTestServlet&lt;/url-pattern&gt;&lt;br /&gt;&lt;/filter-mapping&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oprócz strategii filtru standardowego w literaturze [ALUR2004,Crawford] spotyka się również rozwiązania bazujące na własnej implementacji klasy &lt;span style="font-weight:bold;"&gt;FilterManager&lt;/span&gt; oraz klasy &lt;span style="font-weight:bold;"&gt;FilterChain&lt;/span&gt;. Nie są one jednak tak uniwersalne i przenośne jak przedstawiona strategia filtru standardowego, dlatego nie zostaną przeze mnie omówione.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Podsumowanie wzorca&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Wykorzystanie wzorca Intercepting Filter wiąże się z pewnymi aspektami, z których projektant musi zdawać sobie sprawę. Jak zawsze są pozytywne oraz negatywne strony wykorzystania pewnych rozwiązań.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Centralizacja sterowania przy użyciu niezależnych od siebie procedur obsługi (np. autoryzacja, logowanie, szyfrowanie)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Poprawa wielokrotnego użycia&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Deklaratywna i elastyczna konfiguracja&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Złe strony wzorca &lt;span style="font-weight:bold;"&gt;Intercepting Filter&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Mało wydajna wymiana danych pomiędzy filtrami&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Context Object&lt;/h2&gt;&lt;br /&gt;Pisząc aplikacje często zdarza się, że wiążemy ją bardzo mocno z protokołem, w jakim pracuje. Bardzo częste są sytuacje, że w ramach całego programu wykorzystujemy obiekty &lt;span style="font-weight:bold;"&gt;HttpServletRequest&lt;/span&gt;. Poza brakiem możliwości zmiany protokołu komunikacyjnego takiego systemu, pojawia się bardzo duży problem z testowanie takiej aplikacji.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Należy używać wzorca &lt;span style="font-weight:bold;"&gt;Context Object&lt;/span&gt; w celu hermetyzacji stanu w sposób niezależny od protokołu i udostępniania go kolejnym elementom aplikacji. Trzy poniższe rysunki przedstawiają diagram klas i sekwencji wzorca. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDq_ifIG_I/AAAAAAAAEQM/crtQOtrvkW4/s1600-h/ContextObject(diagram_klas).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDq_ifIG_I/AAAAAAAAEQM/crtQOtrvkW4/s400/ContextObject(diagram_klas).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215426745805052914" /&gt;Context Object diagram klas&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDrIUCUOEI/AAAAAAAAEQU/hmtw9hppr5I/s1600-h/ContextObject(strategia_kontekstu_zadania).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDrIUCUOEI/AAAAAAAAEQU/hmtw9hppr5I/s400/ContextObject(strategia_kontekstu_zadania).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215426896544938050" /&gt;Context Object dla protokołu HTTP&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDrUAlzI3I/AAAAAAAAEQc/LYMUhtjTXLU/s1600-h/ContextObject(diagram_sekwencji).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDrUAlzI3I/AAAAAAAAEQc/LYMUhtjTXLU/s400/ContextObject(diagram_sekwencji).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215427097483486066" /&gt;Context Object diagram sekwencji&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Najczęstszą strategią implementacji wzorca Context Objet jest strategia kontekstu żądania w postaci mapy. Stan żądania jest przekształcany do postaci standardowej implementacji interfejsu &lt;span style="font-weight:bold;"&gt;Map&lt;/span&gt;, która jest przekazywana dalej. Zaletą tego rozwiązania jest jego prostota. Niestety jest też ujemna strona tego rozwiązania, a wiąże się ona ze słabym typowaniem parametrów przechowywanych w mapie, które są zrzutowanie na bazową klase &lt;span style="font-style:italic;"&gt;Object&lt;/span&gt;. Poniżej przedstawiona jest przykładowa implementacja:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class FrontController extends HttpServlet {&lt;br /&gt;...&lt;br /&gt;  private void processRequest(HttpServletRequest request,&lt;br /&gt;                              HttpServletResponse response)&lt;br /&gt;                              throws ServletException, java.io.IOException {&lt;br /&gt;&lt;br /&gt;    // tworzenie obiektu RequestContext przy użyciu strategii mapy&lt;br /&gt;    Map requestContextMap = new HashMap(request.getParameterMap());&lt;br /&gt;    Dispatcher dispatcher = new Dispatcher(request, response);&lt;br /&gt;    requestContextMap.put("dispatcher", dispatcher);&lt;br /&gt;&lt;br /&gt;    // utworzenie instancji ApplicationController&lt;br /&gt;    ApplicationController applicationController = new ApplicationControllerImpl();&lt;br /&gt;&lt;br /&gt;    // przetwarzanie żądania&lt;br /&gt;    ResponseContext responseContext =&lt;br /&gt;      applicationController.handleRequest(requestContextMap);&lt;br /&gt;&lt;br /&gt;    // przetwarzanie odpowiedzi&lt;br /&gt;    applicationController.HandleResponse(requestContextMap,responseContext);&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;h3&gt;Podsumowanie&lt;/h3&gt;&lt;br /&gt;Dobre strony wzorca \textsl{Context Object}:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Ułatwia pielęgnację i umożliwia ponowne wykorzystanie.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ułatwia testowanie - ze względu na wykorzystanie standardowych obiektów Javy możliwe jest testowanie aplikacji za pomocą standardowych narzędzi takich jak JUnit.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Zmniejszone ograniczenia związane ze zmianą interfejsów.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Złe strony:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Zmniejszona wydajność.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Composite View&lt;/h2&gt;&lt;br /&gt;Tworzenie złożonych wizualnie stron internetowych jest skomplikowaną sprawą. W przypadku kiedy tworzymy całe serwisy, wiele stron jest do siebie podobnych, lub nawet zawiera te same elementy (fragmenty szaty graficznej, system menu, itp.). Wstawianie ich na każdą stronę z osobna sprawia, że późniejsza modyfikacja tych elementów jest niezwykle pracochłonna, lub też czasami nawet nie możliwa. &lt;br /&gt;&lt;br /&gt;Zastosowanie wzorca Composite View umożliwia konstruowanie dokumentów stron WWW poprzez złożenie elementów składowych, np. na podstawie szablonu wyglądu. Umożliwia on wprowadzenie wspólnych nagłówków, stopek, paneli nawigacyjnych w wielu miejscach dowolnego z generowanych dokumentów. W rozwiązaniach bazujących na tym wzorcu układ dokumentu wynikowego może być konfigurowany niezależnie od prezentowanej zawartości. &lt;br /&gt;&lt;br /&gt;Composite View umożliwia również stworzenie rozwiązania w którym w prosty sposób możemy dostosować prezentowaną informację do roli użytkownika (np. kupujący, sprzedający, administrator systemu) aktualnie przeglądającego serwis WWW. Rysunek poniżej przedstawia standardową budowę strony WWW na przykładzie serwisu &lt;a href="http://www.e-informatyka.pl"&gt;www.e-informatyka.pl&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDsfe3cXmI/AAAAAAAAEQk/EG8OML5kg7Y/s1600-h/CompositeView(przyklad).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDsfe3cXmI/AAAAAAAAEQk/EG8OML5kg7Y/s400/CompositeView(przyklad).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215428394100743778" /&gt;Przykładowa struktura strony WWW&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Poniżej wypunktowane są kluczowe czynniki, które powinniśmy rozpatrzyć w celu podjęcia decyzji o zastosowaniu wzorca Composite View:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Potrzeba zastosowania wspólnych podwidoków (nagłówków, stopek, tabel), używanych w wielu miejscach. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Częsta konieczność zmiany wspólnych elementów wielu widoków (np. szaty graficznej).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Chęć uniknięcia powielania elementów, oraz modułowa budowa strony widoku. &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Rysunek poniżej przedstawia diagram klas wzorca Composite View. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDs6t3R8JI/AAAAAAAAEQs/QyXWbcfdyDc/s1600-h/CompositeView(diagram_klas).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WQe-sgAKj6g/SGDs6t3R8JI/AAAAAAAAEQs/QyXWbcfdyDc/s400/CompositeView(diagram_klas).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215428861983060114" /&gt;Composite View diagram klas&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Opis poszczególnych elementów wzorca:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Client&lt;/span&gt; - wybiera widok. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;View&lt;/span&gt; - reprezentuje wyświetlaną stronę. Każdy obiekt View, może być obiektem typu \textsl{SimpleView} albo CompositeView.&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;SimpleView&lt;/span&gt; - reprezentuje podstawowy element składowy widoku złożonego. Nazywany jest też &lt;span style="font-style:italic;"&gt;podwidokiem&lt;/span&gt; lub &lt;span style="font-style:italic;"&gt;segmentem widoku&lt;/span&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;CompositeView&lt;/span&gt; - składa się z kilku obiektów typu \textsl{View}.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Template&lt;/span&gt; - reprezentuje szablon widoku.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;ViewManager&lt;/span&gt; - używa obiektu \textit{Template} do utworzenia rozkładu strony, w której osadzona jest następnie odpowiednia zawartość. Umożliwia on niezależne zarządzanie zawartością i układem strony.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDtgzQTEHI/AAAAAAAAEQ0/-DF3JBZJIHk/s1600-h/CompositeView(diagram_sekwencji).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDtgzQTEHI/AAAAAAAAEQ0/-DF3JBZJIHk/s400/CompositeView(diagram_sekwencji).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215429516265197682" /&gt;Composite View diagram sekwencji&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Istnieje kilka strategii implementacji wzorca &lt;span style="font-weight:bold;"&gt;Composite View&lt;/span&gt; na platformie J2EE. Do najczęściej wykorzystywanych należą strategie zarządzania widokiem za pomocą:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;komponentów Java Beans,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;znaczników standardowych,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;znaczników własnych,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;przekształceń (np. XML + XSTL).&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;W strategii wykorzystującej pierwszej, komponenty Java Beans odpowiadają za generowanie poszczególnych widoków. Przykład strony wykorzystującej to rozwiązanie znajduje się poniżej. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib uri="/web-INF/corej2eetaglibrary.tld" prefix="cjp" %&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;jsp:useBean id="contentFeeder"&lt;br /&gt;  class="javabean.ContentFeeder" scope="request" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;table valign="top" cellpadding="30%"  width="100%"&amp;gt;&lt;br /&gt; &lt;br /&gt;  &amp;lt;cjp:personalizer interest='global'&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;&amp;lt;c:out value="${contentFeeder.worldNews}"/&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;  &amp;lt;/cjp:personalizer&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Rozwiązanie wykorzystujące standardowe znaczniki JSP, jest przez wielu ekspertów [Alur2004,Crawford] uważane za bardziej "&lt;span style="font-style:italic;"&gt;eleganckie&lt;/span&gt;". Związane jest to z faktem całkowitego wyeliminowania kodu Javy z głównego widoku. Taka strategia umożliwia zastosowanie podziału odpowiedzialności (ang. "separation of concern" [Sherif2000]), w którym osoba odpowiedzialna za przygotowanie szaty graficznej (np. grafik komputerowy), nie musi umieć programować a jedynie wykorzystywać elementy przygotowane przez inne osoby. Kod zamieszczony poniżej przedstawia rozwiązanie bazujące na znacznikach standardowych JSP (element jsp:include oraz @include, odpowiadają kolejno za statyczne oraz dynamiczne dołączenie zewnętrznego podwidoku).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;jsp:include page="/jsp/banner.seg" flush="true"/&amp;gt; &lt;br /&gt;&amp;lt;table&amp;gt;&lt;br /&gt;  &amp;lt;tr&amp;gt;&lt;br /&gt;    &amp;lt;td&amp;gt;&lt;br /&gt;    &amp;lt;jsp:include page="/jsp/CompositeView/javabean/ProfilePane.jsp" &lt;br /&gt;      flush="true"/&amp;gt; &lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;td&amp;gt;&lt;br /&gt;       &amp;lt;td&amp;gt;&amp;lt;%@ file="news/worldnews.html" %&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Strategia oparta na znacznikach własnych, jest rozszerzeniem strategii poprzedniej. Znaczniki własne są potężnym mechanizmem zarządzania zawartością i układem strony. Pomimo zwiększonego nakładu pracy programistów (proces tworzenia własnych znaczników jest złożony), jest to rozwiązanie preferowane [Alur 2004]. Zamieszczony poniżej kod przedstawia sposób wykorzystania własnych znaczników w procesie przygotowania strony. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;region:render template='/jsp/CompositeView/templates/portal.jsp'&amp;gt;&lt;br /&gt;  &amp;lt;region:put section='banner' content='/jsp/CompositeView/templates/banner.jsp' /&amp;gt;&lt;br /&gt;  &amp;lt;region:put section='controlpanel' content='/templates/ProfilePane.jsp' /&amp;gt;&lt;br /&gt;  &amp;lt;region:put section='mainpanel' content = '/templates/mainpanel.jsp' /&amp;gt;&lt;br /&gt;  &amp;lt;region:put section='footer' content='/templates/footer.jsp' /&amp;gt;&lt;br /&gt;&amp;lt;/region:render&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;trategia bazująca na przekształceniach, to z reguły rozwiązania bazujące na XML'u oraz XSLT. Jest to rozwiązanie o największych możliwościach, ale jednocześnie najmniejszej efektywności. Widok może być wielokrotnie transformowany zanim zostanie przekazany klientowi, a każda z transformat może być niezależnie wymieniana na inną. Rozwiązanie takie jest nieocenione, kiedy z naszej aplikacji korzysta wielu klientów o różnych możliwościach (np. przeglądarka internetowa, urządzenia PDA, telefony komórkowe, itp.). Powstało wiele środowisk wspierających taką strategie np. &lt;span style="font-style:italic;"&gt;Cocoon (http://cocoon.apache.org/)&lt;/span&gt;. Idea działąnia przekształceń została przedstawiona na poniższym rysunku.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDvCixDotI/AAAAAAAAEQ8/UgtvgNSCXpI/s1600-h/CompositeView(przeksztalcenia).jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WQe-sgAKj6g/SGDvCixDotI/AAAAAAAAEQ8/UgtvgNSCXpI/s400/CompositeView(przeksztalcenia).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215431195466375890" /&gt;Composite View strategia z wykorzystaniem przekształceń&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Podsumowanie&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Wprowadzenie wzorca \textsl{Composite View} pociąga za sobą pewne konsekwencje, z których powinniśmy zdawać sobie sprawę. Oprócz pozytywnych aspektów zastosowania tego rozwiązania istnieją również słabe strony. Do plusów niewątpliwie moglibyśmy zaliczyć:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Poprawę modularności i możliwość ponownego wykorzystania kodu. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Możliwość dodania kontroli opartej na regułach. Do takich reguł może należeć rola użytkownika lub pewne ustawienia systemowe.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ułatwienie pielęgnacji kodu. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Istnieje jednak kilka negatywnych aspektów: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Utrudnienie zarządzania kodem. Związane to jest z możliwością powstawania błędów wyświetlania podczas łączenia kilku elementów w jednym widoku. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Zmniejszenie wydajności - związane z koniecznością dynamicznego tworzenia widoku na żądanie klienta.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Zakończenie&lt;/h2&gt;&lt;br /&gt;Dokument ten stanowi jedynie wstęp do tematyki wzorców projektowych warstwy prezentacji platformy J2EE. Pokazuje jednak jak ważną rolę mogą one odegrać w procesie projektowania aplikacji. Pozwalają zredukować koszty wytworzenia systemu, dzięki zastosowaniu sprawdzonych rozwiązań. Dzięki wzorcom możemy także efektywniej komunikować się o obrębie zespołów projektowych. &lt;br /&gt; &lt;br /&gt;Nie należy jednak zapominać, że wzorzec projektowy stanowi jedynie szablon pewnego rozwiązania. Szablon ten następnie może być zaimplementowany za pomocą kilku strategii. Starałem się wraz z omawianiem każdego wzorca przejście od zdefiniowania problemu jaki nas dotyczy, przez wybranie ogólnego rozwiązania (wzorca projektowego), aż do jego szczegółowej implementacji będącej strategią.&lt;br /&gt; &lt;br /&gt;Należy zdawać sobie jednak sprawę, że wykorzystywanie wzorców projektowych pomimo niezliczonej ilości korzyści generuje pewien narzut. Narzutem tym może być zwiększona liczba linii kodu, jaki należy wpisać, może być nim również zwiększony czas wykonywania się naszego programu. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bibliografia&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;[ALUR2004] - D.Alur, J.Crupi, D.Malks, "Core J2EE Wzorce projektowe"&lt;br /&gt;[Crawford] - W.Crawford, J.Kaplan, "J2EE Stosowanie wzorców projektowych"&lt;br /&gt;[Sherif2000] - M.Y.Sherif,  H.H.Ammar, "Pattern-Oriented Analysis and Design: Composing Patterns to Design Software Systems"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1215190753075844274?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1215190753075844274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1215190753075844274' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1215190753075844274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1215190753075844274'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/wzorce-projektowe-warsty-prezentacji.html' title='Wzorce projektowe warsty prezentacji'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDkASOV6FI/AAAAAAAAEPE/oa6Ql6ooReo/s72-c/Praktyki(ModulSterujacy).jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7030791561999799977</id><published>2008-06-24T13:49:00.005+02:00</published><updated>2009-02-27T06:30:30.111+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Bezpieczny to_param</title><content type='html'>Wykorzystując Ruby on Rails chcielibyśmy tworzyć bardziej przyjazne/opisowe adresy url. Weźmy za przykład &lt;a href="http://www.ncbiuletyn.pl"&gt;biuletyn rynku New Connect&lt;/a&gt;. W biuletynie tym znajdują się linki do bieżących lub archiwalnych artykułów. Byłoby lepiej, żeby zamiast wywołania www.ncbiuletyn.pl/czytaj/1, zobaczyć www.ncbiuletyn.pl/czytaj/1-debiuty_sierpniowe.html&lt;br /&gt;&lt;br /&gt;Aby osiągnąć taki efekt nie musimy za wiele robić wystarczy nadpisać w klasie modelu metodę to_param. Możemy to zrobić w taki sposób:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; def to_param&lt;br /&gt;    "#{self.id}-#{self.tytul}"&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Musimy jednak pamiętać, że nie każdy ciąg znaków będzie prawidłowym adresem url i niektóre artukuły mogą nam się po prostu przestać wyświetlać. Musimy zatem zabezpieczyć przed tym naszą aplikację i usuwać z pola niedozwolone znaki. Możemy to osiągnąć w poniższy sposób:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; def to_param&lt;br /&gt;    "#{self.id}-#{self.tytul&lt;span style="font-weight:bold;color:red;"&gt;.gsub(/(\W)/,"_")&lt;/span&gt;}"&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7030791561999799977?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7030791561999799977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7030791561999799977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7030791561999799977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7030791561999799977'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/bezpieczny-toparam.html' title='Bezpieczny to_param'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6506108912259164021</id><published>2008-06-24T12:58:00.009+02:00</published><updated>2009-02-27T06:11:39.632+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Dodanie counter cache do istniejącej tabeli</title><content type='html'>Dodanie counter cacha do isteniejącej tabeli (dla relacji jeden- wiele) rozpocząć powinniśmy od stworzenia migracji dodającej do tabeli (w obiekcie agregującym) dodatkowej kolumny. Załóżmy w tym przypadku, że w naszej aplikacji posiadamy tabele Miasta oraz tabelę powiaty. Obie są w relacji jeden-do-wielu. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Miasto &lt; ActiveRecord::Base&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "jest wymagana"&lt;br /&gt;  belongs_to :powiat&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Powiat &lt; ActiveRecord::Base&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "jest wymagana"&lt;br /&gt;  has_many :miasta&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Uwaga: jeżeli chcesz używać polskich nazw w modelach przeczytaj &lt;a href="http://mstanek.http://www.blogger.com/img/gl.link.gifblogspot.com/2008/03/ruby-on-rails-202-i-inflections.html"&gt;ten artykuł&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Zanim przejdziemy do modyfikacji tabel zaznaczmy w modelu, że chcemy używać kolumny counter_cache. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Miasto &lt; ActiveRecord::Base&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "jest wymagana"&lt;br /&gt;  belongs_to :powiat, &lt;span style="font-weight:bold;color:red;"&gt;:counter_cache =&gt; true;&lt;/span&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Następnie dodajmy migrację:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;script/generate migration powiaty_add_counter_cache&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W migracji wpisujemy następujący kod&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; add_column :powiaty, :miasta_count, :integer, :default =&gt; 0&lt;br /&gt;    Powiat.find(:all).each do |p|&lt;br /&gt;      &lt;span style="font-weight:bold;color:red"&gt;Powiat.update_counters p.id, :miasta_count =&gt; p.miasta.length&lt;/span&gt;&lt;br /&gt;    end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W tym momencie nasza aplikacja będzie miała prawidłowo ustawione liczniki.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6506108912259164021?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6506108912259164021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6506108912259164021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6506108912259164021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6506108912259164021'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/dodanie-counter-cache-do-istniejcej.html' title='Dodanie counter cache do istniejącej tabeli'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2065100129201614159</id><published>2008-06-24T11:33:00.020+02:00</published><updated>2009-02-27T06:22:49.868+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Counter Cache w ruby on rails dla relacji many-to-many</title><content type='html'>Rails dostarcza wiele cennych narzędzi, które w nieprawdopodobny sposób potrafią przyspieszyć proces tworzenia aplikacji. Jednym z bardzo użytecznych mechanizmów jest wsparcie dla mechanizmu counter cache. &lt;br /&gt;&lt;br /&gt;Aby zrozumieć jak działa ten mechanizm wyobraźmy sobie, że mamy relacje typu jeden do wielu. Dla przykładu w każdym powiecie znajduje się wiele miast. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WQe-sgAKj6g/SGDM0k52NDI/AAAAAAAAEO8/XskT9_3EZN0/s1600-h/miasto-powiat.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_WQe-sgAKj6g/SGDM0k52NDI/AAAAAAAAEO8/XskT9_3EZN0/s320/miasto-powiat.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215393572126602290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Jeżeli chcielibyśmy w naszej aplikacji wyświetlać przy każdym powiecie informacje o liczbie miast jaka sie w nim znajduje musielibyśmy za każdym razem wywołać:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Select count(*) from miasta where powiat_id = id&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Łatwo się zorientować, że jeżeli liczba miast i powiatów jest duża to takie rozwiązanie jest wysoce nieefektywne. Rozwiązaniem staje się wprowadzenie dodatkowej kolumny do tabeli powiaty zawierającą policzoną wcześniej liczbę miast. Teraz pozostaje jedynie pilnowanieaby przy każdym dodaniu lub usunięciu relacji powiat - miasto informacja w dodatkowej kolumnie została zaktualizowana.&lt;br /&gt;&lt;br /&gt;W przypadku przedstawionej tutaj relacji sam Rails czuwa nad tym aby liczba ta pozostała prawidłowa wystarczy, że zrobimy następujące kroki:&lt;br /&gt;&lt;br /&gt;1.Zdefiniujemy migracje:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class CreateRelacja &lt; ActiveRecord::Migration&lt;br /&gt;  def self.up&lt;br /&gt;&lt;br /&gt;    create_table :miasta do |t|&lt;br /&gt;      t.string :nazwa, :limit =&gt; 35&lt;br /&gt;      t.integer :miasto_id&lt;br /&gt;      t.timestamps&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    create_table :powiaty do |t|&lt;br /&gt;      t.string :nazwa, :limit =&gt; 35&lt;br /&gt;      t.integer :miasta_count, :default =&gt; 0&lt;br /&gt;      t.timestamps&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Uwaga: bardzo ważne jest aby kolumna  miasta_count zainicjowana została domyślną wartością 0 – w przeciwnym przypadu licznik nie będzie działał (jeżeli chcesz dodać counter_cache w istniejącej tabeli zobacz tego posta (http://mstanek.blogspot.com/2008/06/dodanie-counter-cache-do-istniejcej.html)).&lt;br /&gt;&lt;br /&gt;2.W następnym kroku należy zmodyfikować klasy modelu:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Miasto &lt; ActiveRecord::Base&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "jest wymagana"&lt;br /&gt;  belongs_to :powiat,:counter_cache =&gt; true;&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;class Powiat &lt; ActiveRecord::Base&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "jest wymagana"&lt;br /&gt;  has_many :miasta&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Takie rozwiązanie jest szybkie i całkowicie wspierane przez Railsa. Niestety wsparcia takiego nie otrzymujemy dla relacji wiele do wiele. &lt;br /&gt;&lt;br /&gt;W tym momencie za model posłuży nam &lt;a href="http://www.informacja.medyczna.pl"&gt;baza usług medycznych informacja-madyczna.pl&lt;/a&gt;. Występuje tam związek pomiędzy specjalizacjami a lekarzami. Jest wielu lekarzy posiadających daną specjalizację, a każdy z nich może posiadać więcej niż jedną specjalizację. Jest to ewidentnie związek wiele do wiele. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDMuKZCBOI/AAAAAAAAEO0/EUJnfFO9qFE/s1600-h/specjalizacja-osoba.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WQe-sgAKj6g/SGDMuKZCBOI/AAAAAAAAEO0/EUJnfFO9qFE/s320/specjalizacja-osoba.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215393461930427618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nasz model wygląda zatem w następujący sposób:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Lekarz &lt; ActiveRecord::Base&lt;br /&gt;  has_and_belongs_to_many :specjalizacje&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Specjalizacja &lt; ActiveRecord::Base&lt;br /&gt;  has_and_belongs_to_many :lekarze&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Aby załóżmy zatem, że chcemy mieć informacje dotyczącą ilości lekarzy z daną specjalizacją. W kodzie informację taką można uzyskać w nastepujący sposób:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Specjalizacja.find_by_nazwa('ginekologia').lekarze.length&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Niestety wyciągnięcie w ten sposób informacji dla każdej specjalizacji jest bardzo czasochłonne. Dodajmy zatem kolumnę licznika w tabeli specjalizacje, tak abyśmy mogli wyliczoną w powyższy sposób liczbę zachować. Tworzymy zatem migrację a w migracji dodajemy następujący kod:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    add_column :specjalizacje, :lekarze_count, :integer, :default =&gt; 0&lt;br /&gt;    Specjalizacja.find(:all).each do |s|&lt;br /&gt;      s.lekarze_count = s.lekarze.length&lt;br /&gt;      s.save&lt;br /&gt;    end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Proszę zauważyć, że aby zachować jednolity zapis z wbudowanym mechanizmem couter_cache kolumna została nazwana w analogiczny sposób. &lt;br /&gt;&lt;br /&gt;W tym momencie posiadamy już informację o liczności każdego związku – jest ona przechowywana w klasie Specjalizacja. Teraz pozostaje najtrudniejsza część, należy mianowicie zadbać o to, żeby w czasie dodawania  bądź usuwania obiektów z relacji licznik ulegał zmianie. Należy tutaj zwrócić uwagę, że modyfikaje tego typu możemy wprowadzać po obu stronach relacji. Pokaże to na przykładzie dodania nowej specjalizacji lekarzowi, którą możemy wykonać na dwa sposoby:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   lekarz = Lekarz.find_by_imie_and_nazwisko('Jan','Kowalski')&lt;br /&gt;   specjalizacja = Specjalizacja.find_by_nazwa('ginekologia')&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;1. sposób:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   lekarz.specjalizacje &lt;&lt; specjalizacja &lt;br /&gt;   lekarz.save&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. sposób:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   specjalizacja.lekarze &lt;&lt; lekarz&lt;br /&gt;   specjalizacja.save&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Z dokumentacji relacji has_many dowiadujemy się, że posiada ona dwa bardzo pomocne nam modyfikatory :before_add oraz :before_remove. Pozwolą nam one na śledzenie zmian, które powinny zostać odzwierciedlone w wartości licznika. Rozszerzmy zatem naszą klasę Lekarz o śledzenie zmian i poprawę licznika:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Lekarz &lt; ActiveRecord::Base&lt;br /&gt;has_and_belongs_to_many :specjalizacje, &lt;br /&gt;             &lt;span style="font-weight:bold; color:red;"&gt;:before_add =&gt; :counter_inc, &lt;br /&gt;             :before_remove =&gt; :counter_dec&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  def counter_inc(t)&lt;br /&gt;    counter_change(t, 1)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def counter_dec(t)&lt;br /&gt;    counter_change(t, -1)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  private&lt;br /&gt;  def counter_change(object, amount)&lt;br /&gt;    object.lekarze_count = object.lekarze_count+amount;&lt;br /&gt;    object.save&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A następnie klasę Specjalizacja&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Specjalizacja &lt; ActiveRecord::Base&lt;br /&gt; has_and_belongs_to_many :lekarze, &lt;br /&gt;             &lt;span style="font-weight:bold; color:red;"&gt;:before_add =&gt; :counter_inc, &lt;br /&gt;             :before_remove =&gt; :counter_dec&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  def counter_inc(t)&lt;br /&gt;    t.counter_inc(self)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def counter_dec(t)&lt;br /&gt;    t.counter_dec(self)&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W tym momencie udało nam się stworzyć mechanizm counter_cache dla relacji wiele do wiele (many-to-many). Oczywiście pozostaje nam napisanie odpowiednich testów, ale to zadanie pozostawiam już czytelnikowi.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2065100129201614159?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2065100129201614159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2065100129201614159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2065100129201614159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2065100129201614159'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/counter-cache-w-ruby-on-rails-dla.html' title='Counter Cache w ruby on rails dla relacji many-to-many'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WQe-sgAKj6g/SGDM0k52NDI/AAAAAAAAEO8/XskT9_3EZN0/s72-c/miasto-powiat.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2858924342289833814</id><published>2008-06-16T16:09:00.009+02:00</published><updated>2009-02-27T06:22:32.188+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Poprawione wyrażenie regularne dla e-maila</title><content type='html'>Ponieważ wyrażenie regularne służące do weryfikacji poprawności e-maila podane w dokumentacji rubiego nie jest doskonałe (zakłada konieczność wprowadzenia e-maila) oraz umożliwia wstawienie w nim znaku '?' poniżej podaje zmodyfikowane wyrażenie nie posiadający w.w. wad:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; validates_format_of :email, &lt;br /&gt;    :with =&gt; &lt;span style="color:red;"&gt;/(^([^@\s?]+)@((?:[-_a-z0-9]+\.)+[a-z]{2,})$)|(^$)/i,&lt;/span&gt;&lt;br /&gt;    :message =&gt; "ma błędny format (przykładowy poprawny email przyklad@domena.pl)"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Korzystając z okazji podam również wyrażenie regularne które może służyć do weryfikacji poprawności wpisanego numeru telefonu:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; validates_format_of :telefon, &lt;br /&gt;    :with =&gt; &lt;span style="color:red;"&gt;/^[+]{0,1}[-0-9()\s]+$/&lt;/span&gt;,&lt;br /&gt;    :message =&gt; "ma błędny format (przykłady poprawnych: +48 071 123 123, 012-12-332)"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2858924342289833814?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2858924342289833814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2858924342289833814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2858924342289833814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2858924342289833814'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/poprawione-wyraenie-regularne-dla-e.html' title='Poprawione wyrażenie regularne dla e-maila'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-1089746364762430097</id><published>2008-06-16T15:53:00.014+02:00</published><updated>2009-02-27T06:20:17.776+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Why ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association arrise?</title><content type='html'>Tworząc zależności wiele do wiele możemy wykorzystać przełącznik through i zapisać w danej asocjacji dodatkowe informacje np. relacja Czytelnik - Artykul, może zawierać np. ocenę wystawioną danemu artykułowi. Nie wchodząc w szczegóły jak tworzyć takie związki (na sieci znajduje się kilka dość dobrych tutoriali które łątwo wygooglować), czasami napotkać na poniższy wyjątek:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aby rozwiązać ten problem należy pamiętać, że klasa będąca złączeniem musi być jawnie dodana do zależności w klasach bazowych. Na przykładzie:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Lekarz &lt; ActiveRecord::Base&lt;br /&gt;   has_many :placowki, :through =&gt; :pracownicy&lt;br /&gt;   &lt;span style="color:red;"&gt;has_many :pracownicy&lt;/span&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Placowka &lt; ActiveRecord::Base&lt;br /&gt;  has_many :lekarze, :through =&gt; :pracownicy&lt;br /&gt;  &lt;span style="color:red;"&gt;has_many :pracownicy&lt;/span&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Pracownik &lt; ActiveRecord::Base&lt;br /&gt;  belongs_to :lekarz&lt;br /&gt;  belongs_to :placowka&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-1089746364762430097?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/1089746364762430097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=1089746364762430097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1089746364762430097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/1089746364762430097'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/why-activerecordhasmanythroughassociati.html' title='Why ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association arrise?'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7269135343204857955</id><published>2008-06-09T01:44:00.008+02:00</published><updated>2009-02-27T06:31:23.888+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>LightWindow 2 i problem z flashowymi bannerami</title><content type='html'>Korzystając z doskonałego skryptu tworzącego tak zwany LightWindow (http://mysticearth.wordpress.com/2007/07/12/lightwindow-2-available/), napotkałem na dość uciążliwy problem. Sprawa polega na tym, że okno podglądu tworzone jest dynamicznie po kliknięciu na link. Zanim wyświetlony zostanie podgląd zlinkowanego zasobu biblioteka generuję animację rozwijającą w dość atrakcyjny sposób okienko. Wszystko jest dobrze, aż do momentu kiedy animacja ta nie jest wyświetlana na stronie, która zawiera flashowe dodatki. Efekt jest taki, że wszystkie flasha znajdują się nad animowaną warstwą okienka podglądu. Ostateczny wygląd jest dosyć nieciekawy. &lt;br /&gt;&lt;br /&gt;Rozwiązań problemu jest zapewne wiele, ale ostatecznie zdecydowałem się na metodę, polegającą na tym, że wszystkie elementy flashowe przed wywołaniem okienka light window są ukrywane, a po jego wyłączeniu na nowo pokazywane. &lt;br /&gt;&lt;br /&gt;Aby osiągnąć taki efekt należy skorzystać z dobrodziejstw jakie daje nam biblioteka Prototype (standardowo dołączana do projektu). &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;     swfobject.embedSWF("&amp;lt;%= url %&amp;gt;", "banner_&amp;lt;%=  banner.id %&amp;gt;", "700", "100", "9.0.0");&lt;br /&gt;  &amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;a href="http://&amp;lt;%= banner.url %&amp;gt;" style="position:relative;z-index:1;" class="banner"&amp;gt;&lt;br /&gt;     &amp;lt;div id="banner_&amp;lt;%=  banner.id %&amp;gt;" style="z-index:1;" &amp;gt;&lt;br /&gt;      &amp;lt;p&gt;&amp;lt;img src="&amp;lt;%= @url_for_app +banner.plik.public_filename if banner.plik %&gt;"/&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;     &amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Uwaga: do osadzenia obiektu Flash została użyta biblioteka SWFObject (gorąco polecam).&lt;br /&gt;&lt;br /&gt;Następnie modyfikujemy dwie funkcji w lightwindow.js. Szukamy następującej linijki:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   activate : function(e, link){  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dla ułatwienia powiem że jest to linia 252 i na samym początku dodajemy następujący wiersz:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;($$('.banner').invoke('hide'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Następnie w funkcji dekatywacji (linia 277):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; deactivate : function(){&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;wstawiamy &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;       ($$('.banner').invoke('show'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dzięki takim kosmetycznym zmianom nasz problem został rozwiązany.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7269135343204857955?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7269135343204857955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7269135343204857955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7269135343204857955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7269135343204857955'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/lightwindow-2-i-problem-z-flashowymi.html' title='LightWindow 2 i problem z flashowymi bannerami'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-8672125090964649025</id><published>2008-06-09T01:18:00.023+02:00</published><updated>2009-02-27T06:21:25.855+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Przekazanie bloku kodu do metody helpera</title><content type='html'>Korzystanie z dobrodziejstwa rubiego jakim jest przekazywanie bloku kodu do metody można wykorzystywać projektując metody w klasach Helperów. Aby wykorzystać ten mechanizm należy jednak zastosować specjalną kontrukcję, którą pokrótce postaram się wyjaśnić.&lt;br /&gt;&lt;br /&gt;Załóżmy, że projektowana przez nas witryna składa się z wielu modułów, z których każdy posiada nagłówek oraz treść. Za każdym razem te dwie rzeczy opakowywane są w serię divów z przypisanymi odpowidnimi klasami. Nasze zadanie polegać będzie na tym aby napisać metodę w klasie ApplicationHelper umożliwiającą wstawienie wspomnianego modułu w dowolnym widoku.&lt;br /&gt;&lt;br /&gt;Zacznijmy więc od definicji metody:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def modul_tematyczny(tytul, &amp;block) &lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Następnie w widoku umieśćmy następujące wywołanie:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;div ....&amp;gt; .... &amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;% modul_tematyczny("Wstawiony modul") do %&amp;gt;&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;     &amp;lt;% @wiadomosci.each do |wiadomosc|%&amp;gt;&lt;br /&gt;        &amp;lt;li&gt; &amp;lt;%= wiadomosc.temat-%&amp;gt; - &amp;lt;%= wiadomosc.updated_at %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;     &amp;lt;% end %&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;  &amp;lt;% end%&amp;gt;&lt;br /&gt;  &amp;lt;div ....&amp;gt; .... &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Powróćmy w do helpera i dodajmy odpowiedni kod, tak aby wszystko razem zaczęło działać:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def modul_tematyczny(tytul, &amp;block) &lt;br /&gt;&lt;span style="font-weight:bold;"&gt; blok = capture(&amp;block)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;res = &amp;lt;&amp;lt;HTML&lt;br /&gt;  &amp;lt;div class="modul"&amp;gt;&lt;br /&gt;    &amp;lt;h1 class="tytul"&amp;gt;#{tytul}&amp;lt;/h1&amp;gt;&lt;br /&gt;    &amp;lt;div class='zawartosc'&amp;gt;&lt;br /&gt;      #{blok}&lt;br /&gt;    &amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;/div&amp;gt;&lt;br /&gt;HTML&lt;br /&gt;&lt;br /&gt; &lt;span style="font-weight:bold;"&gt;concat(res, block.binding)&lt;/span&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Jak nie trudno zauważyć całą magię stanowią dwa wywołania, które wiążą blok kodu ze zmienną, a następnie zwracają wynik. Zastosowany przykład jest wysoce niedoskonały, ale daje pogląd na możliwości jakie daje nam definiowanie helperów wykorzystujących bloki kodu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-8672125090964649025?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/8672125090964649025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=8672125090964649025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8672125090964649025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/8672125090964649025'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/przekazanie-bloku-kodu-do-metody.html' title='Przekazanie bloku kodu do metody helpera'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-2835814852793868938</id><published>2008-06-02T23:47:00.005+02:00</published><updated>2009-02-27T06:31:30.345+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Problem z podwójnym kliknięciem w LightWindow 2</title><content type='html'>Mam przyjemność być użytkownikiem jednej z lepszych bibliotek JavaScript do generowania tak zwanych Light Box/Window http://www.stickmanlabs.com/lightwindow/. Niestety zauważyłem, że posiada ona dość nieprzyjemny mankament objawiający się podczas podwójnego kliknięcia na linku z przypisanym stylem lightwindow. Domyślnie biblioteka rozbudowuje dla takiego elementu drzewo DOM dodając mu właściwość onClick. Niestety jeżeli nastąpi podwójne kliknięcie ramka zwiększa swoją szerokość dwa razy, co w niektórych przypadkach powoduje że staje sie szersza niż okno przeglądarki. Bezpośrednia ingerencja w bibliotekę nie jest trywialna jednak prosty trick zastosowany (niestety na każdym łączu ze stylem lightwindow) pozwala rozwiązać problem. Wystarczy dopisać:&lt;br /&gt;&lt;br /&gt;ondblclick="return false;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-2835814852793868938?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/2835814852793868938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=2835814852793868938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2835814852793868938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/2835814852793868938'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/06/problem-z-podwjnym-klikniciem-w.html' title='Problem z podwójnym kliknięciem w LightWindow 2'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7902544602273143442</id><published>2008-03-28T13:34:00.012+01:00</published><updated>2009-02-27T06:13:25.012+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Rails a upload plików z klasą polimorficzną (Attachment_fu)</title><content type='html'>Polecam zainstalowanie plug-inu Attachment_fu&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Następnie tworzymy model np. File /lub plik - tworząc odpowiednie inflections/, czyli&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;scrip/generate model Plik&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;w stworzona migracja powinna wyglądać następująco:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class CreatePliki &lt; ActiveRecord::Migration&lt;br /&gt;  def self.up&lt;br /&gt;      create_table :pliki do |t|&lt;br /&gt;      t.column :filename, :string&lt;br /&gt;      t.column :size, :integer&lt;br /&gt;      t.column :content_type, :string&lt;br /&gt;      t.column :thumbnail, :string&lt;br /&gt;      t.column :parent_id, :integer&lt;br /&gt;      t.column :height, :integer&lt;br /&gt;      t.column :width, :integer&lt;br /&gt;      &lt;br /&gt;      # Obsługa polimorfizmu&lt;br /&gt;      t.column :zasob_id, :integer&lt;br /&gt;      t.column :zasob_type, :string&lt;br /&gt;      &lt;br /&gt;      t.timestamps&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.down&lt;br /&gt;    drop_table :pliki&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A nasz plik modelu powinien zawierać następujący wpis:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Plik &lt; ActiveRecord::Base&lt;br /&gt;  belongs_to :zasob, :polymorphic =&gt; true # Polimorfizm&lt;br /&gt;  &lt;br /&gt;  has_attachment :content_type =&gt; :image, &lt;br /&gt;                   :storage =&gt; :file_system, &lt;br /&gt;                   :max_size =&gt; 2.megabytes,&lt;br /&gt;                   :resize_to =&gt; '300x300&gt;',&lt;br /&gt;                   :size =&gt; 0..2.megabyte,&lt;br /&gt;                   :thumbnails =&gt; {&lt;br /&gt;                      :small =&gt; '50x50&gt;',&lt;br /&gt;                      :medium =&gt; '100x100&gt;',&lt;br /&gt;                      :big =&gt; '200x200&gt;'&lt;br /&gt;                   },&lt;br /&gt;                   :processor =&gt; :MiniMagick;&lt;br /&gt;&lt;br /&gt;  validates_as_attachment&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Zdefiniowane zostały tutaj opcje zapisu zdjęcia uwzględniające tworzenie miniaturek za pomocą biblioteki MiniMagic. Aby ją zainstalować powinniśmy wpisać w konsoli:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;sudo gem install mini_magick&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Teraz wiążemy nasze zdjęcie z jakąś istniejącą klasą modelu. W naszym przypadku niech będzie nią klasa produkt:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Produkt &lt; ActiveRecord::Base&lt;br /&gt;&lt;br /&gt;  has_and_belongs_to_many :kategorie&lt;br /&gt;  belongs_to :producent&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;  has_one :plik, :as =&gt; :zasob #,:class_name =&gt; 'Plik'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  validates_presence_of :nazwa, :message =&gt; "nie może być pusta"&lt;br /&gt;  validates_presence_of :cena, :message =&gt; "nie może być pusta"&lt;br /&gt;  &lt;br /&gt;  validates_length_of :nazwa, :minimum=&gt;2, :message=&gt; "musi składać się przynajmniej z dwóch znaków"&lt;br /&gt;  validates_numericality_of :cena, :greater_than_or_equal_to =&gt; 0, :message =&gt; "nie może być ujemna"&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W następnej kolejności musimy uzupełnić widoki o możliwość dodawania oraz wyświetlania naszego obrazka. W formularzu dla akcji new oraz edit powinniśmy mieć następujący wpis&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;% form_for(@produkt, :html =&gt; { :multipart =&gt; true }) do |f| %&gt;&lt;br /&gt;  ....&lt;br /&gt;  &lt;%= file_field :plik, :uploaded_data %&gt;&lt;br /&gt;  ....&lt;br /&gt;&lt;% end %&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Musimy również uzupełnić nasz kotroler o zapis załączonego pliku. W akcji update oraz create należy dodać następujący kod:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   unless params[:plik].blank?&lt;br /&gt;      @produkt.plik = Plik.new(params[:plik])&lt;br /&gt;      p.save &lt;br /&gt;   end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wyświetlić nasz załączony plik możemy w następujący sposób:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;%= image_tag(@produkt.plik.public_filename(:big)) if @produkt.plik%&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;gdzie :big to nazwa thumbnailsa podana w modelu. Jeżeli nie podamy tego parametru wyświetlony będzie oryginalny obrazek.&lt;br /&gt;&lt;br /&gt;Przedstawiłem podstawowe kroki niezbędne do dodania możliwości przechowywania plików związanych z naszymi klasami modelu. Po więcej informacji odsyłam do:&lt;br /&gt;&lt;br /&gt;http://www.railslodge.com/plugins/108-attachment-fu&lt;br /&gt;http://clarkware.com/cgi/blosxom/2007/02/24&lt;br /&gt;http://blog.defv.be/2007/12/19/attachment_fu-with-polymorphic-association&lt;br /&gt;http://khamsouk.souvanlasy.com/2007/5/1/ajax-file-uploads-in-rails-using-attachment_fu-and-responds_to_parent&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7902544602273143442?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7902544602273143442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7902544602273143442' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7902544602273143442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7902544602273143442'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/rails-upload-plikw-z-klas-polimorficzn.html' title='Rails a upload plików z klasą polimorficzną (Attachment_fu)'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-7146060218317395475</id><published>2008-03-28T12:33:00.005+01:00</published><updated>2008-06-16T16:22:25.484+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Ruby MySQL i UTF8</title><content type='html'>Najprostszy sposób na ustawienie MySQL do pracy w UTF-8, to modyfikacja pliku my.cnf. Plik ten znajduje się w katalogu /etc/mysql/my.cnf. W pliku tym w sekcji zmodyfikować 2 sekcje [mysqld] oraz [client]:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;[mysqld]&lt;/span&gt;&lt;br /&gt;character-set-server            = UTF8  &lt;br /&gt;default-character-set           = UTF8  &lt;br /&gt;collation_server            = utf8_polish_ci&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;[client]&lt;/span&gt;&lt;br /&gt;default-character-set=utf8&lt;br /&gt;&lt;br /&gt;Następnie aby ruby poprawnie radził sobie z zapisem do tak stworzonej bazy należy zmodyfikować plik environment.rb znajdujący się w podkatalogu /config/. Do pliku tego dodajemy następujący wpis:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;  config.action_controller.default_charset = "utf-8"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jeżeli tworzyliśmy projekt za pomocą rails -d mysql nazwa_projektu automatycznie w pliku konfigurującym połączenie z baza danych powinniśmy otrzymać podobny zestaw wpisów:&lt;br /&gt;&lt;br /&gt;development:&lt;br /&gt;  adapter: &lt;span style="font-weight:bold;"&gt;mysql&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;  encoding: utf8&lt;/span&gt;&lt;br /&gt;  database: projekt_development&lt;br /&gt;  username: root&lt;br /&gt;  password: &lt;br /&gt;  socket: /var/run/mysqld/mysqld.sock&lt;br /&gt;&lt;br /&gt;/Podobmne wpisy będą wygenerowane również dla środowiska &lt;span style="font-style:italic;"&gt;test&lt;/span&gt; oraz &lt;span style="font-style:italic;"&gt;production&lt;/span&gt;/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Uwaga:&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt; jeżeli pomimo wprowadzenia zmian opisanych powyżej nasza baza danych dalej błędnie obsługuje polskie znaki dialektyczne, najprostszym sposobem aby sobie z tym poradzić jest usunąć wszystkie tabele i stworzyć je na nowo /&lt;span style="font-weight:bold;"&gt;rake db:create:all&lt;/span&gt; oraz &lt;span style="font-weight:bold;"&gt;rake migrate&lt;/span&gt;/.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-7146060218317395475?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/7146060218317395475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=7146060218317395475' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7146060218317395475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/7146060218317395475'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/ruby-mysql-i-utf8.html' title='Ruby MySQL i UTF8'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6225882282610512490</id><published>2008-03-20T20:41:00.009+01:00</published><updated>2009-02-27T06:25:53.703+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Ruby on Rails - polskie komunikaty błędów przy walidacji</title><content type='html'>W przypadku używania walidatorów dla stron polskojęzycznych pojawia się problem z niezręcznymi angielskimi komunikatami błędów. Aby spolonizować w prosty sposób nasze komunikaty wystarczy dokonać tylko kilku modyfikacji. &lt;br /&gt;&lt;br /&gt;Załóżmy, że w naszym modelu mamy następującą klasę:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;i&gt;class&lt;/i&gt;&lt;/strong&gt; Produkt &lt; ActiveRecord::Base&lt;br /&gt;#pola =&gt; Nazwa, Cena,&lt;br /&gt;&lt;strong&gt;&lt;i&gt;end&lt;/i&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Spolonizowana walidacja mogłaby wyglądać w takim przypadku następująco:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;i&gt;class&lt;/i&gt;&lt;/strong&gt; Produkt &lt;strong&gt;   validates_presence_of&lt;/strong&gt; :nazwa, :&lt;strong&gt;message&lt;/strong&gt; =&gt; "nie może być pusta"&lt;br /&gt;&lt;strong&gt;   validates_presence_of &lt;/strong&gt;:cena,&lt;strong&gt; :message&lt;/strong&gt; =&gt; "nie może być pusta"&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;   validates_length_of &lt;/strong&gt;:nazwa, :minimum=&gt;2, &lt;strong&gt;:message&lt;/strong&gt;=&gt; "musi składać się przynajmniej z dwóch znaków"&lt;br /&gt;&lt;strong&gt;   validates_numericality_of :&lt;/strong&gt;cena,&lt;i&gt; :greater_than_or_equal_to&lt;/i&gt; =&gt; 0,&lt;strong&gt; :message&lt;/strong&gt; =&gt; "nie może być ujemna"&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;i&gt;end&lt;/i&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;W tym momencie część pracy już za nami. Metoda&lt;br /&gt;&lt;strong&gt;&lt;i&gt;&lt;br /&gt;&lt;%= error_message_for :produkt -%&gt;&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;&lt;/strong&gt;działa już prawie tak jak byśmy chcieli. Pozostaje usunięcie nagłówka i wstępnego komunikatu, który w dalszym ciągu pojawia się w języku angielskim. Rozwiązanie jest dość trywialne (oczywiście jeżeli wiadomo gdzie szukać). Poprawiona wersja metody wygląda więc tak:&lt;br /&gt;&lt;br /&gt;&lt;%= error_messages_for :produkt, :header_message =&gt; "Błąd !", :message =&gt; "Lista błędów:"%&gt;&lt;br /&gt;&lt;br /&gt;Polecam również lekturę: &lt;br /&gt;http://www.rubyonrails.pl/forum/p3572-2007-10-22-00:50:44&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6225882282610512490?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6225882282610512490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6225882282610512490' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6225882282610512490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6225882282610512490'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/ruby-on-rails-polskie-komunikaty-bdw.html' title='Ruby on Rails - polskie komunikaty błędów przy walidacji'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-3792131290640356222</id><published>2008-03-19T20:57:00.004+01:00</published><updated>2009-02-27T06:25:56.270+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Rails paginacja z polskimi nazwami w osobnej metodzie helpera</title><content type='html'>Aby nie powielać wpisywanego kodu paginatora (will_paginate) parametryzując go o polskie napisy dla przycisków 'next' i 'previous' możemy stworzyć oddzielną metodę w module ApplicationHelper.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def paginacja(kolekcja)&lt;br /&gt;       will_paginate kolekcja, &lt;br /&gt;            :inner_window =&gt; 10, &lt;br /&gt;            :outer_window =&gt; 10, &lt;br /&gt;            :prev_label =&gt; "« Poprzednie", &lt;br /&gt;            :next_label =&gt; "Następne »"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Następnie w widoku możemy wywołać tą metodę w następujący sposób.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;%= paginacja @produkty %&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oczywiście aby działała cała paginacja należy zainstalować plugin will_paginate oraz przygotować odpowiednio kolekcję w kontrolerze:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@produkty = Produkt.paginate(:order =&gt; 'nazwa DESC',&lt;br /&gt;                               #:conditions =&gt; ["active = ?", 1]&lt;br /&gt;                               :per_page =&gt; 10,&lt;br /&gt;                               :page =&gt; params[:page])&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Jeżeli przeczytałeś ten artykuł do końca to prawdopodobnie zainteresuje Ciebie również &lt;a href="http://mstanek.blogspot.com/2008/06/paginacja-w-rails-21-gem-willpaginate.html"&gt;paginacja w Rails 2.1&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-3792131290640356222?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/3792131290640356222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=3792131290640356222' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3792131290640356222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/3792131290640356222'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/rails-paginacja-z-polskimi-nazwami-w.html' title='Rails paginacja z polskimi nazwami w osobnej metodzie helpera'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-4395967551087028041</id><published>2008-03-19T13:55:00.003+01:00</published><updated>2009-02-27T06:30:35.703+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Umieszczenie grafiki w link_to</title><content type='html'>Aby umieścieć obrazek w hiperłączu wystarczy w widoku *.html.erb dodać następującą linijkę:&lt;br /&gt;&lt;br /&gt;&lt;%= link_to image_tag("obrazek.gif", :border=&gt;0), :action =&gt; 'akcja', :id =&gt; obiekt %&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-4395967551087028041?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/4395967551087028041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=4395967551087028041' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4395967551087028041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/4395967551087028041'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/umieszczenie-grafiki-w-linkto.html' title='Umieszczenie grafiki w link_to'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-6363512879061774182</id><published>2008-03-18T22:42:00.005+01:00</published><updated>2009-02-27T06:26:00.219+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><title type='text'>Ruby on Rails 2.0.2 i inflections (polski pluralize)</title><content type='html'>Ruby posiada fantastyczną cechę jaką jest możliwość odmiany rzeczowników i na ich podstawie automatycznego tworzenia nazw tabel oraz kontrolerów. Niestety własność ta działa standardowo tylko dla języka angielskiego. Jeżeli chcemy jednak aby w naszym projekcie była możliwość posługiwania się nazwami polskimi możemy dodać nowe reguły do railsa, które umożliwią mu odmianę polskich wyrazów.&lt;br /&gt;&lt;br /&gt;Sprawa odmiany wydaje się w railsie 2.0.2 dość trywialna. Wystarczy dodać do pliku config/initializers/inflections.rb kilka linijek. Pamiętajmy jednak, że rails do prawidłowego działania potrzebuje poprawnie zdefiniowane reguły dla języka angielskiego dlatego nie usuwajmy tych reguł metodą clear :all.&lt;br /&gt;&lt;br /&gt;Nowe polskie rzeczowniki możemy dodawać jako rzeczowniki nieregularne i w takim przypadku rails nie protestuje i wszystkie inne funkcjonalności powinny działać poprawnie wpisujemy więc:&lt;br /&gt;&lt;br /&gt;Inflector.inflections do |inflect|&lt;br /&gt;    inflect.irregular 'konto', 'konta'&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;I wywolujac &lt;strong&gt;"&lt;/strong&gt;&lt;strong&gt;script/generate model Konto uzytkownik:string haslo:string"&lt;/strong&gt;, a następnie &lt;strong&gt;"rake db:migrate" &lt;/strong&gt;w naszej bazie danych powstanie tabela konta.&lt;br /&gt;&lt;br /&gt;Problem pojawi się jeżeli będziemy chcieli użyć naszych rzeczowników w metodzie scaffold. Domyślnie nie są generowane odpowiednie ścieżki routingu dlatego musimy to naprawić wpisując:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;rake routes&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;Od teraz możemy cieszyć się polskimi nazwami w railsie. &lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-6363512879061774182?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/6363512879061774182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=6363512879061774182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6363512879061774182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/6363512879061774182'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2008/03/ruby-on-rails-202-i-inflections.html' title='Ruby on Rails 2.0.2 i inflections (polski pluralize)'/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23574449.post-114172576972852955</id><published>2006-03-07T11:01:00.001+01:00</published><updated>2008-03-28T14:00:13.135+01:00</updated><title type='text'></title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/4428/2424/640/20060128_IMG_3365_2.jpg"&gt;&lt;img style="margin: 0px 10px 10px 0px; float: left;" alt="" src="http://photos1.blogger.com/blogger/4428/2424/320/20060128_IMG_3365_2.jpg" border="0" /&gt;&lt;/a&gt;test&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23574449-114172576972852955?l=mstanek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mstanek.blogspot.com/feeds/114172576972852955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23574449&amp;postID=114172576972852955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/114172576972852955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23574449/posts/default/114172576972852955'/><link rel='alternate' type='text/html' href='http://mstanek.blogspot.com/2006/03/sdasdasdasdasdasdasdfasdfaskdfals.html' title=''/><author><name>Michał Stanek</name><uri>http://www.blogger.com/profile/01862714591514637942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://3.bp.blogspot.com/_WQe-sgAKj6g/Sad3K3pOVmI/AAAAAAAAHKw/4sTvRZIh98I/S220/IMG_7433.JPG'/></author><thr:total>0</thr:total></entry></feed>
