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

<channel>
	<title>ninajansen.dk &#187; ruby</title>
	<atom:link href="http://ninajansen.dk/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://ninajansen.dk</link>
	<description></description>
	<lastBuildDate>Thu, 23 Apr 2009 21:46:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Introducing Cloud: an open-source ruby wordcloud generator</title>
		<link>http://ninajansen.dk/2009/04/23/introducing-cloud-an-open-source-ruby-wordcloud-generator/</link>
		<comments>http://ninajansen.dk/2009/04/23/introducing-cloud-an-open-source-ruby-wordcloud-generator/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 21:46:33 +0000</pubDate>
		<dc:creator>Nina Jansen</dc:creator>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://ninajansen.dk/?p=91</guid>
		<description><![CDATA[I&#8217;ve just put out a new gem &#8220;cloud&#8221; that I&#8217;ve been working with on and off for the past few months. You can find it on github, it&#8217;s called ninajansen-cloud. I&#8217;ve also made a repository with examples which you can also find on github ninajansen-cloud_examples.
My motivation for this gem is that I love making wordclouds [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just put out a new gem &#8220;cloud&#8221; that I&#8217;ve been working with on and off for the past few months. You can find it on github, it&#8217;s called <a href="http://github.com/ninajansen/cloud/tree/master">ninajansen-cloud</a>. I&#8217;ve also made a repository with examples which you can also find on github <a href="http://github.com/ninajansen/cloud_examples/tree/master">ninajansen-cloud_examples</a>.</p>
<p>My motivation for this gem is that I love making wordclouds with <a href="http://www.wordle.net/">wordle</a>. However there are a bunch of things about wordle that I don&#8217;t love. It&#8217;s closed source, so you can&#8217;t take it apart and hack it. Also, it only runs in you browser as a java app. I wanted to be able to generate wordclouds as a background process. Eventually, I want to be able to make a cloud out of anything, like a table in a database. I want to be able to run cloud generating as a background process in my rails app. All this will not work with a closed source in-browser java project.</p>
<p>Now, I am not, nor is anyone else permitted to reverse engineer wordle, and I have certainly not done that. I don&#8217;t know what algortihm wordle code uses, it is certainly much faster than the one I came up with. Cloud is slow, can&#8217;t insert words inside other word, and can only generate pdf-files, which must be post-processed by some other code to make it into other formats. The only redeeming quality is that it is open source and I am really hoping that there are other people out there who would like to spend some time making cloud much better.</p>
<p>I use a 2D binpacking algorithm for cloud. To start with, I use <a href="http://ruby-pdf.rubyforge.org/pdf-writer/">pdf:writer</a>&#8217;s built in pdf-functions to compute the size of a box that a word takes up. I add up the total area, and add some extra just in case, and find the smallest possible paper size that has this area and is avaible in pdf. Since pdf is scalable, you can always transform your clouds to some uniform size later, if you want. Once I have all the boxes, I take the largest and place it at the center of the canvas. I then add all the corners and centers of the sides of the box to an array. I look through this array of points to find the one that is closest to the &#8220;center&#8221; of the canvas. The center is computed by one of several distance functions, so it is possible to make clouds of different shapes. Once I have found the point closest to the center, I take the next box, and place it&#8217;s opposite point there (if the point is at the center of the righthand edge of the box, I place the center, lefthand edge of the second box at the point). Then I check if this placement is okay, i.e. if it doesn&#8217;t overlap with any other boxes. If it is okay, great, I have placed the second box and I can add it&#8217;s points to my &#8220;possible locations&#8221; array. If not, I try to place it at another point. I keep going until all boxes are placed. I clean up points regularly, i.e. I try to place the smallest possible wordbox at each point, and if it cannot be placed I erase the points from my &#8220;possible locations&#8221; array.</p>
<p>This algorithm gets slower and slower the more boxes (words) there are. The first 100 words are definitely faster to place than the next 100 words. 100 words takes about a minute. I&#8217;ve added speed to the algorithm by using ruby inline and written some of the functionality in C. Still, you wouldn&#8217;t want to generate very large clouds this way. But if you want to put a wordcloud on the front page of your website with treding topics, you could easily run cloud periodically in the background.</p>
<p>I hope that someone would like to use this gem, and contribute to it. You could add more color palettes or distance functions, incoorporate it into rails or just use it and tell me what you think.</p>
<img src="http://ninajansen.dk/?ak_action=api_record_view&id=91&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://ninajansen.dk/2009/04/23/introducing-cloud-an-open-source-ruby-wordcloud-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cool complicated logic trick: use eval</title>
		<link>http://ninajansen.dk/2008/11/03/cool-complicated-logic-trick-use-eval/</link>
		<comments>http://ninajansen.dk/2008/11/03/cool-complicated-logic-trick-use-eval/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 10:42:39 +0000</pubDate>
		<dc:creator>Nina Jansen</dc:creator>
				<category><![CDATA[eval]]></category>
		<category><![CDATA[logic]]></category>
		<category><![CDATA[ruby]]></category>
<category>eval</category><category>logic</category><category>ruby</category>
		<guid isPermaLink="false">http://ninajansen.dk/?p=57</guid>
		<description><![CDATA[So I am working on an application where I have an array where I need to the sum of the values of members of the array, if they fulfill certain conditions. It looks like this:
if !A and !B
array.each do {&#124;a&#124; if (some condition) sum += a }
if A and !B
array.each do {&#124;a&#124; if (some other [...]]]></description>
			<content:encoded><![CDATA[<p>So I am working on an application where I have an array where I need to the sum of the values of members of the array, if they fulfill certain conditions. It looks like this:</p>
<p>if !A and !B</p>
<p>array.each do {|a| if (some condition) sum += a }</p>
<p>if A and !B</p>
<p>array.each do {|a| if (some other condition) sum += a}</p>
<p>etc.</p>
<p>Now this can easily become much more complicated if there are more flags that can change what needs to be done inside the loop,  i.e. which members of the array should be added to the sum and which shouldn&#8217;t. For each possible permutation you spawn a whole bunch of code that essentially does the same thing. I solved this problem by using the eval function.</p>
<p>The eval functions takes a string and evaluates it as code. So for instance, eval(&#8220;1 == 1&#8243;) would return true. You can use this to make an array of strings with stuff that needs to be done inside that loop. As an example consider this:</p>
<p>conditions = Array.new</p>
<p>if params[:some_id] != 0 : conditions &lt;&lt; &#8220;self.some_id == params[:some_id]&#8221; end</p>
<p>You can add more conditions, depending on parameters passed to the function and then join them together:</p>
<p>conditions_string = conditions.join(&#8216; &amp;&amp; &#8216;)</p>
<p>Then you only need to make one loop:</p>
<p>array.each do {|a| if eval (conditions_string) sum += a }</p>
<p>You could, of course, join the conditions array with || or include the logical operator in the string itself.</p>
<img src="http://ninajansen.dk/?ak_action=api_record_view&id=57&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://ninajansen.dk/2008/11/03/cool-complicated-logic-trick-use-eval/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
