<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Diving into code</title>
	<atom:link href="http://tomek.codequest.eu/feed/" rel="self" type="application/rss+xml" />
	<link>http://tomek.codequest.eu</link>
	<description></description>
	<pubDate>Mon, 12 Oct 2009 09:10:51 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Let’s dive into code!</title>
		<link>http://tomek.codequest.eu/2009/04/28/let%e2%80%99s-dive-into-code/</link>
		<comments>http://tomek.codequest.eu/2009/04/28/let%e2%80%99s-dive-into-code/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 13:42:49 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Experiments]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=72</guid>
		<description><![CDATA[I love screencasts! Screencasts are an easy and fun way to learn new technologies. If you want to avoid fluff, dive directly into code&#8230; screencasts are one of the best tools to achieve it!

I was impressed with a great work done by Geoffrey Grosenbach from PeepCode or guys like Bill Dudney or Ryan Bates who [...]]]></description>
			<content:encoded><![CDATA[<p>I love screencasts! Screencasts are an easy and fun way to learn new technologies. If you want to avoid fluff, dive directly into code&#8230; screencasts are one of the best tools to achieve it!</p>
<p>
I was impressed with a great work done by <a href="http://geoffreygrosenbach.com/">Geoffrey Grosenbach</a> from <a href="http://peepcode.com/">PeepCode</a> or guys like <a href="http://bill.dudney.net/roller/objc/">Bill Dudney</a> or <a href="http://railscasts.com">Ryan Bates</a> who publish their recordings under <a href="http://www.pragprog.com/">Pragmatic Programmer</a> umbrella. I have bought almost all material they have produced and it was money well spent.
</p>
<p>
After watching a few of their episodes I understood I would love to follow into their footsteps and start to produce my own screencasts. A few months later, working after hours I finished my online store and recorded <a href="http://www.codequest.eu/screencasts/stripes_fundamentals">Stripes fundamentals</a>.
</p>
<p>
It is the first out of a series of screencasts that map out how to use Stripes to solve everyday web application development challenges in a simple and efficient way. The whole series is based on application-centric approach where the development of an online shop application drives the coverage of Stripes.</p>
<p>
At <a href="http://www.codequest.eu">code quest</a> I don&#8217;t want to focus only on one domain or technology. The upcoming screencast will be dedicated to deployment on Ubuntu. I am recording it together with my friend <a href="http://jdn.pl/user/1">Piotr Maj</a> and it should be available by the end of May. Please stay tuned!</p>
<p>
I hope screencasts published at code quest will help developers learn in a fast and efficient way. My goal is to produce high quality stuff at a reasonable price. And my hope is that you’ll help me achieve this goal. It is an agile project and you get to help steer.</p>
<p>I look forward to your feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2009/04/28/let%e2%80%99s-dive-into-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Patterns of project behavior</title>
		<link>http://tomek.codequest.eu/2009/01/02/patterns-of-project-behavior/</link>
		<comments>http://tomek.codequest.eu/2009/01/02/patterns-of-project-behavior/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 18:08:28 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Bookshelf]]></category>

		<category><![CDATA[Peopleware]]></category>

		<category><![CDATA[book]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=45</guid>
		<description><![CDATA[Tom DeMarco is one of my favorite technical writers.
Recently, on a blog of one my friends, I have read a recommendation for Deadline by Tom DeMarco.
I fully agree with my friend that this easy, entertaining book provides some valuable ideas about how to improve a project and can be a great read for a software [...]]]></description>
			<content:encoded><![CDATA[<p>Tom DeMarco is one of my favorite technical writers.</p>
<p>Recently, on a <a href="http://jarmark.org/post/nieoczekiwana-zmiana-miejsc/">blog of one my friends</a>, I have read a recommendation for <a href="http://www.amazon.com/Deadline-Novel-About-Project-Management/dp/0932633390/ref=pd_bbs_sr_4?ie=UTF8&#038;s=books&#038;qid=1230645421&#038;sr=8-4" rel="nofollow">Deadline</a> by Tom DeMarco.</p>
<p>I fully agree with my friend that this easy, entertaining book provides some valuable ideas about how to improve a project and can be a great read for a software engineer who has been moved to project manager role.</p>
<p>In addition to Deadline I would like to recommend another book by Tom DeMarco I have just read - <a href="http://www.amazon.com/Adrenaline-Junkies-Template-Zombies-Understanding/dp/0932633676/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1230645557&#038;sr=1-1" rel="nofollow">Adrenaline Junkies and Template Zombies</a>.</p>
<p>Software engineers should be aware of elegant solutions to common problems in software design. They should know patterns for managing object creation, composing objects into larger structures, and coordinating control flow between objects. They should also recognize and correct bad habits of code and design.</p>
<p>I believe the same story is with project managers.</p>
<p>Project Manger should know good patterns to follow and anti-patterns that should be avoided.</p>
<p>Tom DeMarco together with the team of his friends from the Atlantic Systems Guild has done a nice job and described 86 patterns of project behavior.</p>
<p>Patterns can be read in a moment. Each pattern is about two pages long with titles that build strong association in the brain&#8230; e.g. adrenaline junkies, dead fish, project sluts, template zombies&#8230;</p>
<p>You won&#8217;t be surprised how often you will say&#8230; &#8220;Ahh&#8230; I recognize it&#8230; somebody is spying on my company&#8230; this is exactly what is happening right now in my project&#8230;&#8221;</p>
<p>I strongly believe this is a fun, interesting read for all software engineers and project members and&#8230; definitely the must read for project managers who want to avoid pitfalls and boost effectiveness of their teams.</p>
<p>Adrenaline Junkies and Template Zombies can be consumed in an evening or during a longer flight with very little effort.</p>
<p>If you normally fall asleep while reading books about project management, give Adrenaline Junkies and Template Zombies a try. I am sure you won&#8217;t be disappointed!</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2009/01/02/patterns-of-project-behavior/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to write a custom form builder in Rails?</title>
		<link>http://tomek.codequest.eu/2008/12/28/how-to-write-a-custom-form-builder-in-rails/</link>
		<comments>http://tomek.codequest.eu/2008/12/28/how-to-write-a-custom-form-builder-in-rails/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 18:00:16 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Software]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=44</guid>
		<description><![CDATA[Most of the current web applications contain many different types of forms. Usually they look very similar across the whole application and they are a source of repetitive code in your presentation layer.
In this blog post I would like to share with you how to minimize this repetitive code and make your form nice, concise [...]]]></description>
			<content:encoded><![CDATA[<p>Most of the current web applications contain many different types of forms. Usually they look very similar across the whole application and they are a source of repetitive code in your presentation layer.</p>
<p>In this blog post I would like to share with you how to minimize this repetitive code and make your form nice, concise and dry by writing custom form builders.</p>
<p>Let&#8217;s say you are building a new web application with your close friend. He is a ninja of css, a web standards orthodox and requires that application generate forms that look like the piece of html below.</p>
<pre>
&lt;form action="/users" class="new_user" id="new_user" method="post"&gt;
&lt;fieldset&gt;
&lt;legend&gt;Sign up:&lt;/legend&gt;
&lt;dl class="required correct"&gt;
&lt;dt&gt;&lt;label for="user_login"&gt;Login&lt;/label&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;input id="user_login" name="user[login]" size="30" type="text" value="tomek" /&gt;&lt;/dd&gt;
&lt;dd class="notice"&gt;Lowercase letters (a-z) &amp; numbers only - no spaces.&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class="required error"&gt;
&lt;dt&gt;&lt;label for="user_email"&gt;E-mail&lt;/label&gt;&lt;/dt&gt;
&lt;dd class="error"&gt;can't be blank&lt;/dd&gt;
&lt;dd&gt;&lt;input id="user_email" name="user[email]" size="30" type="text" value="" /&gt;&lt;/dd&gt;
&lt;dd class="notice"&gt;We won't get you spammed!&lt;/dd&gt;&lt;/dl&gt;
...
&lt;/fieldset&gt;
&lt;/form&gt;
</pre>
<p>You are fully aware you cannot generate this kind of html with the standard helper methods provided by Rails.</p>
<p>On the one hand you don&#8217;t want to upset your friend and even start negotiations on how forms should be styled. On the other hand you would like to keep the code of your view concise and easy to maintain&#8230; let&#8217;s say more or less like the snippet below.</p>
<pre>
&lt;% form_for @user do |f| -%&gt;
&lt;fieldset&gt;
&lt;legend&gt;Sign up:&lt;/legend&gt;
&lt;%= f.text_field :login, :notice =&gt; "Lowercase letters (a-z) &amp; numbers only - no spaces." %&gt;
&lt;%= f.text_field :email, :label =&gt; 'E-mail', :notice =&gt; "We wont get you spammed, we promise!" %&gt;
...
&lt;/fieldset&gt;
&lt;% end -%&gt;
</pre>
<p>Well&#8230; in tis situation&#8230; there is no other way. You have to write your own form builder!</p>
<h4>What is a form builder?</h4>
<p>ActionView::Helpers::FormBuilder is one of the &#8220;hidden hero&#8221; Rails classes. It is used on a frequent basis but not everybody realizes it even exists.</p>
<p>Whenever you use form_for helper in your view template, you pass an instance of FormBuilder class to the block associated with the method. Look at the snippet above. This is f variable.</p>
<p>So&#8230; if you want to create your own LabeledFormBuilder class with the enriched functionality all you need is to subclass ActionView::Helpers::FormBuilder and instruct Rails to use it. There are a few ways to do it.</p>
<p>One of the solutions is to create a new folder with Ruby file that will contain LabeledFormBuilder class and add it to load paths of Rails environment.</p>
<p>Let&#8217;s say you have just created a folder named builders with labeled_form_builder.rb file under app directory of your application. In order to tell Rails to load ruby code located in this place you have to add one line to your environment.rb file.</p>
<pre>
# app/config/envirnoment.rb
Rails::Initializer.run do |config|
...
config.load_paths += %W( #{RAILS_ROOT}/app/builders )
...
end
</pre>
<p>Next time you restart the server Ruby code placed in the labeled_form_builder.rb file will be loaded.</p>
<p>It is high time you rolled up your sleeves and wrote custom form builder!</p>
<p>Below I would like to show exemplary implementation that may help you to stay on speaking terms with your css ninja friend. I will also share a trick that I consider very useful and cool.</p>
<pre>
# app/builders/labeled_form_builder.rb
class LabeledFormBuilder < ActionView::Helpers::FormBuilder

  %w[text_field password_field text_area].each do |method_name|
    define_method(method_name) do |field_name, *args|
      options = args.extract_options!

      # Create field
      field = @template.content_tag(:dt, label(field_name, options[:label]))

      # Add validation errors
      field += field_errors(field_name)

      # Add field element
      field += @template.content_tag(:dd, super)

      # Add notice message
      field += @template.content_tag(:dd, options[:notice], :class => 'notice') if options[:notice]

      # Render field container with all elements
      @template.content_tag(:dl, field, :class => field_style(field_name))
    end
  end

  def check_box(field_name, *args)
    options = args.extract_options!
    @template.content_tag(:dl, super + label(field_name, options[:notice]), :class => "checkbox")
  end

private

  def is_required?(field_name)
    object.class.reflect_on_validations_for(field_name).map(&#038;:macro).include?(:validates_presence_of)
  end

  def has_errors?(field_name)
    object.errors.invalid? field_name
  end

  def field_errors(field_name)
    field_errors = ''
    if has_errors?(field_name)
      object.errors[field_name].each do |msg|
        field_errors += @template.content_tag(:dd, msg, :class => 'error')
      end
    end
    field_errors
  end

  def field_style(field_name)
    field_style = ''
    if is_required?(field_name)
     field_style += 'required'
    end

    if has_errors?(field_name)
     field_style += ' error'
    elsif !object.errors.empty?
     field_style += ' correct'
    end
    field_style
  end    

  def objectify_options(options)
    super.except(:notice, :label)
  end
end
</pre>
<p>Now let me share a trick with you. Please look at is_required method. In the line&#8230;</p>
<pre>
# app/builders/labeled_form_builder.rb
...
object.class.reflect_on_validations_for(field_name).map(&#038;:macro).include?(:validates_presence_of)
...
</pre>
<p>&#8230; I use <a href="http://wiki.rubyonrails.org/rails/pages/Validation+Reflection">validation reflection plugin</a> to find out if a given field is required or not.</p>
<p>I also use a piece of metaprogramming to provide own implementation of text_field, password_field, text_area helper methods.</p>
<p>The only thing that is missing to make this little example work is intruction to Rails to use LabeledFormBuilder instead of the default one. There are two ways you can do it.</p>
<p>First of all you can add builder attribute to form_for helper.</p>
<pre>
&lt;% form_for @user, <strong>:builder =&gt; LabeledFormBuilder</strong> do |f| -%&gt;
&lt;fieldset&gt;
&lt;legend&gt;Sign up:&lt;/legend&gt;
&lt;%= f.text_field :login, :notice =&gt; "Lowercase letters (a-z) &amp; numbers only - no spaces." %&gt;
&lt;%= f.text_field :email, :label =&gt; 'E-mail', :notice =&gt; "We wont get you spammed, we promise!" %&gt;
...
&lt;/fieldset&gt;
&lt;% end -%&gt;
</pre>
<p>Secondly you can go to your environment config file and add one line to register your custom form builder as the default one.</p>
<pre>
# app/config/envirnoment.rb
ActionView::Base.default_form_builder = LabeledFormBuilder
</pre>
<p>That&#8217;s all! Now you can send a message to your friend that his html code is safe and you can open bottle of wine <img src='http://tomek.codequest.eu/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/12/28/how-to-write-a-custom-form-builder-in-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Don&#8217;t cry for me Argentina</title>
		<link>http://tomek.codequest.eu/2008/12/04/dont-cry-for-me-argentina/</link>
		<comments>http://tomek.codequest.eu/2008/12/04/dont-cry-for-me-argentina/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 20:49:12 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<category><![CDATA[personal]]></category>

		<category><![CDATA[travel]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=43</guid>
		<description><![CDATA[I am back. I took almost one month of vacation to make my first steps to South America.
I was traveling around Argentina: learning tango in Buenos Aires, admiring glaciers in El Calafate, playing with whales and penguins in Puerto Madrid, watching the beauty of waterfalls and jungle in Iguazu and learning about history and culture [...]]]></description>
			<content:encoded><![CDATA[<p>I am back. I took almost one month of vacation to make my first steps to South America.</p>
<p>I was traveling around Argentina: learning tango in Buenos Aires, admiring glaciers in El Calafate, playing with whales and penguins in Puerto Madrid, watching the beauty of waterfalls and jungle in Iguazu and learning about history and culture heritage of Argentina in Salta.</p>
<p>Traveling is for me more about gathering new experiences rather than just pure relaxation. If a trip shook up my perception of the world and changed it a little then journey was a success.</p>
<p>My visit to Argentina was definitely successful. My perception of South America and Argentina in particular has changed.</p>
<p>I made friends with people from Chile, Peru and a few other countries, experienced the beauty of Argentina which I will try to share on the <a href="http://www.natrasie.pl/podroznik/tomek/trasa/wokol_argentyny">natrasie.pl</a>.</p>
<p>I am sure I will come back to this part of the world. Don&#8217;t cry for me Argentina. I will be back!</p>
<p>Hasta la vista.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/12/04/dont-cry-for-me-argentina/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Internationalization in Rails 2.2</title>
		<link>http://tomek.codequest.eu/2008/10/18/internationalization-in-rails-22/</link>
		<comments>http://tomek.codequest.eu/2008/10/18/internationalization-in-rails-22/#comments</comments>
		<pubDate>Sat, 18 Oct 2008 13:00:15 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Software]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=42</guid>
		<description><![CDATA[In the darkness of a night, exhausted after long hours of your day-work, you build a new kicking ass web application.
You want to change the world and make your application accessible to all good people out there&#8230; that&#8217;s why your a new-born baby has to speak several languages!
Now with Rails 2.2 it is easy! All [...]]]></description>
			<content:encoded><![CDATA[<p>In the darkness of a night, exhausted after long hours of your day-work, you build a new kicking ass web application.</p>
<p>You want to change the world and make your application accessible to all good people out there&#8230; that&#8217;s why your a new-born baby has to speak several languages!</p>
<p>Now with Rails 2.2 it is easy! All you need to know is two API methods: I18n.transate aka I18n.t and I18n.localize aka I18n.l &#8230;and somebody who can help you with translation to exotic languages like Chinese, Thai or Polish.</p>
<p>In this post you will find a quick, step-by-step tutorial how to add internationalization to your Ruby on Rails application. Please be aware it is a very simple example and you have to &#8220;live on the edge&#8221; to fully benefit from this post&#8230; ok&#8230; no more fluff and let&#8217;s dive into code together!</p>
<p>First of all let&#8217;s create Rails app, freeze edge and create resource to test things out.</p>
<pre>
rails speak2me
cd speak2me
rake rails:freeze:edge
./script/generate resource friend
./script/generate migration AddNameToFriend name:string
</pre>
<p>Now it is time to create a directory named locales which will contain our translations&#8230;.</p>
<pre>
mkdir config/locales
</pre>
<p>&#8230;and create there two translations for English and Polish language</p>
<pre>
# config/locales/en-US.yml
"en-US":
  main:
    hello: "Hello Darling!"
# config/locales/pl-PL.yml
"pl-PL":
  main:
    hello: 'Witaj Kochanie!'
</pre>
<p>In the release 2.2 of Ruby on Rails framework there was introduced the I18n module.</p>
<p>In the configuration file we will encapsulate details of what locales are available, where they are kept, and what is to be used as the default. Let&#8217;s create i18n.rb file under initializers directory.</p>
<pre>
# config/initializers/i18n.rb
I18n.load_path += Dir[ File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}') ]
I18n.default_locale = "en-US"
</pre>
<p>We have just configured I18n module and now it is right time to get use of it in our controller and view files.</p>
<p>First of all let&#8217;s add method to set locale. We will create a before_ﬁlter in the common base class for all of our controllers.</p>
<pre>
class ApplicationController < ActionController::Base
  before_filter :set_locale
protected
  def set_locale
    session[:locale] = params[:locale] if params[:locale]
    I18n.locale = session[:locale] || I18n.default_locale
  end
end
</pre>
<p>Next we will add index.html.erb file with localized version of greeting.</p>
<pre>
# views/friends/index.html.erb
<%= I18n.t "main.hello" %>
</pre>
<p>The only thing left is to update route configuration and test things out.</p>
<pre>
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources :friends
  map.root :controller => 'friends'
end
</pre>
<p>Open your browser and have fun&#8230; default locale is en-US but as soon as you change locale param you will get polish version of text.</p>
<p>
I have mentioned that in order to localize you Rails 2.2 application you should be aware of two API methods: I18n.transate and I18n.localize.</p>
<p>So far we used only alias to one of the methods - I18n.t. So&#8230; what is a function of I18n.localize method?. Well.. this one basically allows you to format Date and Time objects for a certain locale. In order to see it in action we should update our file with polish locale and add one line in view file.
</p>
<pre>
# views/friends/index.html.erb
<%= I18n.t "main.hello" %>
<%= I18n.l Time.now %>
# config/locales/pl-PL.yml
"pl-PL":
    main:
        hello: 'Witaj Kochanie!'

    date:
        formats:
            default: "%d.%m.%Y"
            short: "%e. %b"
            long: "%e. %B %Y"
            only_day: "%e"

        day_names: [Niedziela, Poniedziełek, Wtorek, Środa, Czwartek, Piątek, Sobota]
        abbr_day_names: [N, Pn, Wt, Śr, Cz, Pt, So]
        month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień]
        abbr_month_names: [~, Sty, Lut, Mar, Kwi, Maj, Cze, Lip, Sie, Wrz, Paz, Lis, Gru]
        order: [ :day, :month, :year ]

    time:
        formats:
            default: "%A, %e. %B %Y, %H:%M"
            time: "%H:%M"
            short: "%e. %B, %H:%M"
            long: "%A, %e. %B %Y, %H:%M"
            only_second: "%S"

        am: "przed południem"
        pm: "po południu"
</pre>
<p>That&#8217;s all folks!</p>
<p>For more details about internationalization in the latest version of Ruby on Rails I strongly recommend to visit <a href="http://www.artweb-design.de/">Sven Fuchs&#8217;s blog</a>. You will get knowledge directly from a source.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/10/18/internationalization-in-rails-22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What is omnimemo?</title>
		<link>http://tomek.codequest.eu/2008/09/29/what-is-omnimemo/</link>
		<comments>http://tomek.codequest.eu/2008/09/29/what-is-omnimemo/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 18:17:46 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Experiments]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=41</guid>
		<description><![CDATA[More and more friends ask me what I would like to achieve with omnimemo? What kind of application I am building? What is omnimemo?
Well&#8230; to make the long story short, omnimemo is a service for people who would like to build rock-solid knowledge in a fast and efficient way.
I would like to implement application that [...]]]></description>
			<content:encoded><![CDATA[<p>More and more friends ask me what I would like to achieve with <a href="http://www.omnimemo.com">omnimemo</a>? What kind of application I am building? What is <a href="http://www.omnimemo.com">omnimemo</a>?</p>
<p>Well&#8230; to make the long story short, <a href="http://www.omnimemo.com">omnimemo</a> is a service for people who would like to build rock-solid knowledge in a fast and efficient way.</p>
<p>I would like to implement application that will assist learner in his or her learning process.</p>
<p>It will learn how user learns. By building approximated model of user learning curve, <a href="http://www.omnimemo.com">omnimemo</a> will compute optimum intervals between repetitions.</p>
<p>There are many factors that can be used to build model of learning curve and compute those intervals but in the first version of <a href="http://www.omnimemo.com">omnimemo</a> I will focus on two main contradictory features.</p>
<ul>
<li>in the period of time frequency of repetitions should be as low as possible. The reason for that is that longer time between repetitions of certain material produces stronger association in the brain. This is so called <a href="http://en.wikipedia.org/wiki/Spacing_effect">spacing effect</a>.</li>
<li>&#8230; but students shouldn&#8217;t forget material before repetition, it means intervals between repetitions should be short enough to ensure that the knowledge is still remembered.</li>
</ul>
<p>In the future versions of <a href="http://www.omnimemo.com">omnimemo</a> I would like to combine local features specific to user learning process with the global features of the whole group of learners who try to master given pice of knowledge.</p>
<p>There is several algorithms and methods to choose from and experiment with. It will be interesting!</p>
<p>Apart from approximated model of user learning curve there are two more aspects that are equally important for me in the context of omnimemo.</p>
<p>First of all, I would like to embed in the <a href="http://www.omnimemo.com">omnimemo</a> social aspect of learning process. I would like users to be able to share with their friends material they would like to master and enjoy spirit of collaborative learning. I remember when I was student that I had really good results when I studied with the group of my friends. We shared notes, materials and studied together. It was fun and effective!</p>
<p>Secondly, I would like to make it possible to learn almost everywhere. I would like to build version of <a href="http://www.omnimemo.com">omnimemo</a> for mobile devices.</p>
<p>I definitely need version for my iPhone but I will also build version for <a href="http://code.google.com/android/">Android</a> because I like an idea behind this platform and would like to take this opportunity to master it while building sth useful.</p>
<p>There is still a lot of work in front of me but I strongly believe I can build sth that matters and brings value.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/09/29/what-is-omnimemo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Refactor your wetware</title>
		<link>http://tomek.codequest.eu/2008/09/28/refactor-your-wetware/</link>
		<comments>http://tomek.codequest.eu/2008/09/28/refactor-your-wetware/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 16:33:06 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Bookshelf]]></category>

		<category><![CDATA[Wetware]]></category>

		<category><![CDATA[book]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=40</guid>
		<description><![CDATA[Almost one year ago I had a great chance to speak at the Oredev conference in Malmo, Sweden. It was a new experience for me and opportunity to meet with and listen to very interesting people. One of them was Andy Hunt&#8230; I highly enjoyed his talk. I must admit he was the source of [...]]]></description>
			<content:encoded><![CDATA[<p>Almost one year ago I had a great chance to <a href="http://www.oredev.org/toppmeny/conference/methodstools/inforetrievalwithopensource.4.76e8b1c6112f078db498000125570.html">speak at the Oredev</a> conference in Malmo, Sweden. It was a new experience for me and opportunity to meet with and listen to very interesting people. One of them was <a href="http://blog.toolshed.com/">Andy Hunt</a>&#8230; I highly enjoyed his talk. I must admit he was the source of inspiration and the spark to an idea of a <a href="http://www.omnimemo.com">tool that can help people to learn</a>&#8230; which I am currently working on in my free time.</p>
<p>There are two things I am really passionate about: computers and brains. </p>
<p>I love to program, build software and see how few lines of code can create things that really matter or bring fun.</p>
<p>I also like to debug our mind. I am interested in how we learn, how our memory works, how we can improve it and get most out of our brain. I learn, experiment and read a lot of books in this area. Most of the things Andy presented during his talk in Sweden were nothing new to me&#8230; but the way he did it and the context he put it in was really valuable and enjoyable for me.</p>
<p>Last week I read the latest <a href="http://pragprog.com/titles/ahptl/pragmatic-thinking-and-learning">book by Andy Hunt &#8220;Refactor your wetware&#8221;</a>. It is great book that is fun and really can help to become more effective in learning process!</p>
<p>Easy to read, very pleasantly written with a lot of of examples that are very valuable especially from the perspective of a software developer. It is great introduction to anybody who is interested in the learning process, how our brains are wired, and how to take advantage of our brain’s architecture. It contains ideas and useful tips on how to solve hard problems, get innovative ideas.</p>
<p>It doesn&#8217;t go into details of mnemonics, memorizing techniques or more scientific models of our brain and learning process which in my opinion is only an advantage of this book. Lecture is engaging and motivates to more research in the area.</p>
<p>It is a well structured story that in my opinion should be a must read for all software developers&#8230;. together with another <a href="http://pragprog.com/the-pragmatic-programmer">book by Andy Hunt and Dave Thomas - Pragmatic Programmers</a>.</p>
<p>I strongly encourage you to check this book out. Read it, enjoy it and dedicate yourself to lifelong learning.</p>
<p>Thank you Andy!</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/09/28/refactor-your-wetware/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Snipetag, online game with the purpose</title>
		<link>http://tomek.codequest.eu/2008/07/06/snipetag-online-game-with-the-purpose/</link>
		<comments>http://tomek.codequest.eu/2008/07/06/snipetag-online-game-with-the-purpose/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 19:58:21 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Experiments]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/?p=39</guid>
		<description><![CDATA[Imagine an ideal world where humans solve some problems and computers solve other problems. &#8230;and they both live in harmony. Does it sounds like Matrix? Maybe, but I think it is one of the directions in which web applications will evolve in the near future.
Technology develops and improves with the speed of light. Each year [...]]]></description>
			<content:encoded><![CDATA[<p>Imagine an ideal world where humans solve some problems and computers solve other problems. &#8230;and they both live in harmony. Does it sounds like Matrix? Maybe, but I think it is one of the directions in which web applications will evolve in the near future.</p>
<p>Technology develops and improves with the speed of light. Each year more and more research is done in the area of artificial intelligence, computer vision or pattern recognition. Unfortunately, there are still a lot of tasks that computers cannot solve yet and there is a huge need for human processing power.</p>
<p>Humans can identify objects in a photo or video much more effectively than computers. Humans can transcribe and translate podcasts, identify emotions, fill in questionnaires on a variety of topics. Still only humans can write valuable reviews and blog posts. Machines are not intelligent enough. At least not now.</p>
<p>A few months ago, inspired by work of <a href="http://www.cs.cmu.edu/~biglou/">Luis Van Ahn</a>, I decided to build a game where as people play and have fun they help to solve one of the current challenges in the area of computer vision and content based information retrieval. They help to build a <a href="http://www.snipetag.com/profit">better world.</a></p>
<p><a href="http://www.snipetag.com">Snipetag</a> is game with the purpose! The goal of the game is to retrieve semantics from images and gather data they will contribute to the research in the area of machine recognition of objects in the web of photos. All data will be available for free to any researcher whose work, research could benefit from it.</p>
<p>Don&#8217;t forget the most important thing! Each game you play helps a small, friendly alien lost on the Earth. Here is the <a href="http://www.snipetag.com/story">story of Thomaso Marsjano.</a></p>
<p>Have fun and help to build a <a href="http://www.snipetag.com/profit">better world!</a></p>
<p>Ahhh&#8230; I build this application after hours, so please forgive me bugs. If you find an issue that has to be fixed please don&#8217;t hesitate to send me an <a href="mailto:tomek@codequest.eu">email</a>. I will fix it. <a href="http://www.snipetag.com">Snipetag</a> is one of my experiments and is now in BETA mode.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/07/06/snipetag-online-game-with-the-purpose/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Each travel has its own beginning&#8230;</title>
		<link>http://tomek.codequest.eu/2008/05/13/each-travel-has-its-own-beginning/</link>
		<comments>http://tomek.codequest.eu/2008/05/13/each-travel-has-its-own-beginning/#comments</comments>
		<pubDate>Tue, 13 May 2008 11:28:10 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Experiments]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/2008/05/13/each-travel-has-its-own-beginning/</guid>
		<description><![CDATA[My strong belief is that travelling is more about experiences rather that sights. For me, travel is a process of transformation. If the trip shook your ideas up, if the experience changed you, then the journey was a success.
One of my travels had its beginning a few months ago. I shared an idea with my [...]]]></description>
			<content:encoded><![CDATA[<p>My strong belief is that travelling is more about experiences rather that sights. For me, travel is a process of transformation. If the trip shook your ideas up, if the experience changed you, then the journey was a success.</p>
<p>One of my travels had its beginning a few months ago. I shared an idea with my friend of building a web site where people could describe their travel experience in an intuitive and pleasant way, publish photos as well as keep track of their friends&#8217; journeys and find out more about destinations before booking a trip.</p>
<p>The idea has caught up. Together with the small team of close friends we decided to invest our time and energy. We started a preparation for our first entrepreneurial travel!</p>
<p>For all of us it has been a new experience. What will be our final destination? What kind of obstacles will we encounter on our way? We still don&#8217;t know. The final destination is not the most important thing. What is really significant is new experience we all gain!</p>
<p>Real travel involves meeting people whose viewpoints are completely different from your own, finding out that you still have a lot in common, that you can communicate and learn a lot from one another. From this point of view work on the <a href="http://www.natrasie.pl">natrasie.pl</a> is real travel.</p>
<p><a href="http://www.natrasie.pl">natrasie.pl</a> is built by friends and for friends. We hope that our passion and engagement will help us to organize valuable and interesting place on the Internet for our users.</p>
<p>I invite you to visit our <a href="http://www.natrasie.pl">website</a>&#8230; and please share your experience. Psss&#8230; please forgive us bugs, we are in beta mode now.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/05/13/each-travel-has-its-own-beginning/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to compute SVD and conquer the world before breakfast?</title>
		<link>http://tomek.codequest.eu/2008/03/17/how-to-compute-svd-and-conquer-the-world-before-breakfast/</link>
		<comments>http://tomek.codequest.eu/2008/03/17/how-to-compute-svd-and-conquer-the-world-before-breakfast/#comments</comments>
		<pubDate>Mon, 17 Mar 2008 23:00:00 +0000</pubDate>
		<dc:creator>Tomasz Korzeniowski</dc:creator>
		
		<category><![CDATA[Machine learning]]></category>

		<category><![CDATA[matrix algebra]]></category>

		<guid isPermaLink="false">http://tomek.codequest.eu/2008/03/17/how-to-compute-svd-and-conquer-the-world-before-breakfast/</guid>
		<description><![CDATA[Digg, Face Book and My Space all rolled into one.
Imagine you a serial entrepreneur and would like to conquer the world with a new, kicking ass web application. Digg, Face Book and My Space all rolled into one. You are going to a build perfect tool that will discover a relevant content for you and [...]]]></description>
			<content:encoded><![CDATA[<h3>Digg, Face Book and My Space all rolled into one.</h3>
<p>Imagine you a serial entrepreneur and would like to conquer the world with a new, kicking ass web application. Digg, Face Book and My Space all rolled into one. You are going to a build perfect tool that will discover a relevant content for you and your friends all over the whooooooole web. It will be based on your intentions and intentions of your community. Your idea is great!!!. You can already see yourself on the cover of <a href="http://www.wired.com/">Wired magazine</a>. You will be more popular than David Heinemaier Hanson, Britney Spears and David Beckham all together. You will be a super star. You ARE a super star!!!</p>
<p>You open you machine, start coding, implement the first pages of your application and then&#8230; Boom, bang, boom! The first problem crops up. How to group web sites, blog posts based on their content? How to retrieve semantics from them? How to cluster all this stuff? You google for the solution and after a while you find out that sth called Singular Value Decomposition may help. Old uncle Google says it definitely  sounds like a good &#8220;candidate&#8221; to investigate. Unfortunately, you have to refresh your knowledge about linear algebra. It is awful but if you want to reach for the stars&#8230; No pain no gain!</p>
<h3>Linear algebra comes with help - SVD</h3>
<p>Today I would like to continue with a linear algebra refresher and introduce matrix decomposition with SVD.</p>
<p>Singular Value Decomposition is one of the cluster analysis and noise reduction technique introduced in 1965 by G. Golub and W. Raman. When we compute the SVD of a matrix the goal is to reduce matrix dimensionality by its decomposition into three components and keeping first k singular values. It will give us an approximated representation of the original matrix. A kind of compressed version of the matrix.</p>
<p>There are a lot of practical areas where SVD can be applied. In one of the next posts I would like to present the application of SVD in Information Retrieval where it is used in the process of Latent Semantic Indexing in order to search for documents that meet given query. It is one of the methods that can help in the analysis of text collections. For instance, blog post or other web content exposed to your next generation web application.</p>
<p>Before I share with you code to do all the stuff please grab your pencil plus a notebook and let me share with you in the next few lines how is singular values decomposition computed and approximation of the matrix built.</p>
<p>SVD decomposes matrix into three components: A = USV<sup>T</sup></p>
<ul>
<li><strong>U</strong> - matrix whose columns are the eigenvectors of the AA<sup>T</sup> matrix - called the left eigenvectors</li>
<li><strong>S</strong> - matrix whose diagonal elements are the singular values of A. Please note it is diagonal matrix so its all non-diagonal elements are zero</li>
<li><strong>V</strong> - matrix whose column are the eigenvectors of the A<sup>T</sup>A matrix - called the right eigenvectors</li>
</ul>
<p>Okey-doke&#8230; nice definition but how does it work? Let&#8217;s say we have matrix A</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/04/a-matrix.png" alt="A-matrix.png" border="0" width="137" height="84" /></p>
<p>The first step is to compute a A<sup>T</sup>. If you would like to refresh your memory about matrices and matters related to them please have a look at Matrix cookbook Part <a href="http://tomek.codequest.eu/2008/01/13/matrix-cookbook/">1</a> and <a href="http://tomek.codequest.eu/2008/01/20/matrix-cookbook-part-2/">2</a>. All you have to know is how to transpose matrix and multiply two matrices.</p>
<p>As soon as we have A<sup>T</sup> and A<sup>T</sup>A the next step is to obtain singular values of the matrix. In order to do it we have to compute the eigen values of A<sup>T</sup>A, sort absolute values of them in descending order and just after that place them on the diagonal of S matrix. Don&#8217;t worry, it is easy. Actually, all you need to do is to solve a polynomial equation. Let&#8217;s have a look at all the calculations.</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/calculation-1.png" alt="calculation-1.png" border="0" width="496" height="420" /></p>
<p>Singular values of the matrix are computed. We can construct S matrix.</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/s.png" alt="s.png" border="0" width="142" height="76" /></p>
<p>Fresh coffe on the table and now we are ready to compute V</p>
<p>We will use eigen values of the A<sup>T</sup>A matrix we have just computed and construct eigen vectors.</p>
<p>Let&#8217;s do it for x = 13.32</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/v1.png" alt="V1.png" border="0" width="522" height="496" /></p>
<p>Let&#8217;s repeat the exercise but this time for x = 0.67</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/v2.png" alt="V2.png" border="0" width="466" height="426" /></p>
<p>There we go&#8230; We are almost done. Now we have to place eigenvectors on V matrix and transpose it.</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/v.png" alt="V.png" border="0" width="368" height="145" /></p>
<p>At this point we have to the same calculation but for AA<sup>T</sup> matrix and compute U matrix.</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/u1.png" alt="U1.png" border="0" width="540" height="500" /></p>
<p>&#8230;time for U2</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/u2.png" alt="U2.png" border="0" width="478" height="338" /></p>
<p>Here we go. Matrix reloaded</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/u.png" alt="U.png" border="0" width="194" height="74" /></p>
<p>We have computed U, S and V<sup>T</sup>. Now we have to write unit test&#8230; hmm&#8230; Please grab your pencil again and check with me if USV<sup>T</sup> is the approximation of matrix A.</p>
<p><img src="http://tomek.codequest.eu/wp-content/uploads/2008/03/usv.png" alt="USV.png" border="0" width="485" height="138" /></p>
<p>It looks good. We have decomposed matrix A into three matrices. But&#8230; why do it? How can we benefit from it? We will benefit from it as soon as we built compressed version of the matrix A. In our simple example the matrix is 2-dimensional. Imagine you deal with a matrix with huge dimensionality. Imagine &#8220;gazillions&#8221; of dimensions and  a lot of noise there. It is a situation where you definitely would prefer to deal with approximated version. Fortunately, building an approximation of the original matrix is piece of cake. It is done by truncating the three matrices obtained from a full SVD. All we keep are the first k columns of U, the first k rows of V<sup>T</sup/> and the first k rows and columns of S. As soon as we have done it, we get a compressed version of the matrix A.</p>
<h3>There is more to come&#8230;</h3>
<p>In the next post I will share with you how to apply SVD in the process of Latent Semantic Indexing. You won&#8217;t even need a pencil or a notebook. This time we will write some code. Let&#8217;s apply theory in practice.</p>
<p>I also plan to continue an idea of building the next generation web content filter and focus on data mining techniques that can be useful on the way.</p>
<p>Stay tuned. There is more to come.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomek.codequest.eu/2008/03/17/how-to-compute-svd-and-conquer-the-world-before-breakfast/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
