<?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>Duplo &#187; mildred</title>
	<atom:link href="http://kill-0.com/duplo/category/mildred/feed/" rel="self" type="application/rss+xml" />
	<link>http://kill-0.com/duplo</link>
	<description>Building Blocks &#38; Learning Experiences</description>
	<lastBuildDate>Fri, 05 Aug 2011 15:30:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Rspec 1.1.4 and Helper spec woes</title>
		<link>http://kill-0.com/duplo/2008/08/06/rspec-114-and-helper-spec-woes/</link>
		<comments>http://kill-0.com/duplo/2008/08/06/rspec-114-and-helper-spec-woes/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 04:11:57 +0000</pubDate>
		<dc:creator>ericw</dc:creator>
				<category><![CDATA[mildred]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[1.1.4]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[spec]]></category>

		<guid isPermaLink="false">http://kill-0.com/duplo/2008/08/06/rspec-114-and-helper-spec-woes/</guid>
		<description><![CDATA[I was having all sorts of problems upgrading Mildred to Rails 2.1.  A lot of the errors I was seeing were like the following: ArgumentError in 'TracksController downloading a track by admin should not be a redirection' wrong number of arguments (0 for 1) /Users/ewollesen/src/mildred/app/models/track.rb:52:in `title' /Users/ewollesen/src/mildred/app/models/track.rb:52:in `filename' /Users/ewollesen/src/mildred/app/controllers/tracks_controller.rb:49:in `download' ./spec/controllers/tracks_controller_spec.rb:82: It took me a [...]]]></description>
			<content:encoded><![CDATA[<p>I was having all sorts of problems upgrading Mildred to Rails 2.1.  A lot of the errors I was seeing were like the following:</p>
<pre><code>ArgumentError in 'TracksController downloading a track by admin should not be a redirection'
wrong number of arguments (0 for 1)
/Users/ewollesen/src/mildred/app/models/track.rb:52:in `title'
/Users/ewollesen/src/mildred/app/models/track.rb:52:in `filename'
/Users/ewollesen/src/mildred/app/controllers/tracks_controller.rb:49:in `download'
./spec/controllers/tracks_controller_spec.rb:82:</code></pre>
<p>It took me a good while to figure out what was going on.  The error was strange because as far as I knew, <code>title</code> was a database attribute in the Album model, which was a descendant of ActiveRecord.  There shouldn&#8217;t have been any arguments required.  Indeed, firing up my debugger and running <code>track.album.read_attribute(:title)</code> returned the expected result of &#8220;Test Album 1&#8243;.  I was very puzzled.</p>
<p>I realized that my title method was being overridden, but by what?  I started feeding the title method random arguments in the hopes of learning something new.  It wasn&#8217;t long before I got lucky:</p>
<pre><code>(rdb:1) e track.album.title("x")
NoMethodError Exception: undefined method `content_tag' for #&lt;Album:0x3d5bbfc&gt;</code></pre>
<p>That tipped me off as to what was overriding my title method.  The <code>content_for</code> is part of a pattern I use to set a view&#8217;s title in the layout via a method called <code>title</code> in my <a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Fbranches%2Frails-2.1%2Fapp%2Fhelpers%2Fapplication_helper.rb&amp;rev=552&amp;sc=0"><code>ApplicationHelper</code></a>.  This made me think of how in Rspec 1.1.4, a Helper module is no longer included by default.  I popped over to my <a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Fbranches%2Frails-2.1%2Fspec%2Fhelpers%2Fapplication_helper_spec.rb&amp;rev=0&amp;sc=0"><code>application_helper_spec.rb</code></a> and found something similar to this:</p>
<pre><code>require File.dirname(__FILE__) + '/../spec_helper'

include ApplicationHelper

describe "ApplicationHelper" do</code></pre>
<p>This needed to be changed to:</p>
<pre><code>require File.dirname(__FILE__) + '/../spec_helper'

describe "ApplicationHelper" do

  include ApplicationHelper</code></pre>
<p>Then all was well.  Whew.  Just to be sure I didn&#8217;t run into this sort of thing again, I went ahead and made sure that all of my other Helper specs followed this paradigm.</p>
<p>This is the second time I&#8217;ve run into an issue where RSpec had overridden some seemingly random method in some seemingly random object.  I guess there&#8217;s a lot of magic in there that I don&#8217;t have my head wrapped around yet.  I just wish it were easier to spot!</p>
]]></content:encoded>
			<wfw:commentRss>http://kill-0.com/duplo/2008/08/06/rspec-114-and-helper-spec-woes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How QBeat Works</title>
		<link>http://kill-0.com/duplo/2007/09/12/how-qbeat-works/</link>
		<comments>http://kill-0.com/duplo/2007/09/12/how-qbeat-works/#comments</comments>
		<pubDate>Thu, 13 Sep 2007 05:46:18 +0000</pubDate>
		<dc:creator>ericw</dc:creator>
				<category><![CDATA[mildred]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://kill-0.com/duplo/2007/09/12/how-qbeat-works/</guid>
		<description><![CDATA[QBeat is one piece of the Mildred project. Specifically, QBeat handles the selection of tracks to play. There are a number of subsytems within QBeat that allow tracks to be selected and played. I&#8217;ll start with a list of all the pertinent subsystems, then I&#8217;ll describe the main responsibilities of each subsystem. Subsystems QBeat MPD [...]]]></description>
			<content:encoded><![CDATA[<p>QBeat is one piece of the <a href="http://www.xmtp.net/mildred/" title="Mildred">Mildred</a> project.  Specifically, QBeat handles the selection of tracks to play.  There are a number of subsytems within QBeat that allow tracks to be selected and played.  I&#8217;ll start with a list of all the pertinent subsystems, then I&#8217;ll describe the main responsibilities of each subsystem.</p>
<h3>Subsystems</h3>
<ul>
<li>QBeat</li>
<li>MPD</li>
<li>MpdMonitor</li>
<li>Selector
<ul>
<li>WeightedSelector
<ul>
<li>Stats</li>
<li>Weight</li>
</ul>
</li>
</ul>
</li>
<li>Schedule</li>
<li>TimeSlot</li>
<li>ProgrammingBlock</li>
<li>Fetcher</li>
</ul>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fq_beat.rb&amp;rev=0&amp;sc=0" title="QBeat">QBeat</a></h3>
<p>QBeat is the glue that holds all the other pieces together.  It gets things rolling, daemonizes the process, opens log files, handles signals, etc.  Once the housekeeping is done, QBeat enters a loop, passing control to the various subsystems as appropriate.</p>
<h3>MPD</h3>
<p>MPD, the <a href="http://www.musicpd.org/" title="Music Player Daemon">Music Player Daemon</a>, is a wholly separate program, one that QBeat uses to handle the nitty gritty of playing audio files. QBeat simply tells MPD which files to play, and MPD takes care of opening the files, and sending them to the appropriate audio devices.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fmpd_monitor.rb&amp;rev=0&amp;sc=0" title="MpdMonitor">MpdMonitor</a></h3>
<p>The MpdMonitor monitors the MPD playlist (imagine that!) It checks the MPD playlist&#8217;s length, and indicates to the Selector if a track should be added to the playlist.   When additional tracks are to be queued, the Selector picks the tracks, and MpdMonitor feeds this information to MPD.  MpdMonitor also monitors the currently playing track, and reports new tracks as they are played.  Lastly, MpdMonitor trims the MPD playlist whenever it grows too long.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fselector.rb&amp;rev=0&amp;sc=0">Selector</a></h3>
<p>Selector is an abstract class, meaning it is meant to be extended, not used as is.   It provides the basic interface expected of a Selector.  A Selector&#8217;s job is to actually pick the next track (or tracks) to queue.</p>
<p>The Selector class also provides a number of utility functions to derivative Selectors.  These functions help with such tasks as loading tracks from ProgrammingBlocks, filtering tracks by user-specified criteria (such as minimum time, or minimum rating), and determining (with help from the ProgrammingBlock) if a single track, whole album, or power block should be queued.</p>
<p>QBeat was designed to allow Selectors to be changed easily.  This allows for the easy development of new Selectors, with totally different selection behavior.  For example, in addition to WeightedSelector, I have a few test selectors which do such things as selecting tracks 100% at random, or selecting tracks in alphabetical order by title.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fweighted_selector.rb&amp;rev=0&amp;sc=0" title="WeightedSelector">WeightedSelector</a></h3>
<p>WeightedSelector is a derivative Selector, and the one generally in use by QBeat.  It evaluates each track, and assigns it a weight.  Weights are based on when the track, its album, and its artist were last queued, as well as their ratings. Last queued and rating data are normalized, and their sum becomes the track&#8217;s weight.  Special modifications are made to reduce the effect of high ratings, or to weight new tracks more heavily.  The final track to be selected is picked at random from the top weighted tracks.</p>
<p>WeightedSelector is where most of QBeat&#8217;s time is spent.  It is also where I spend the most of my time tweaking, debugging, and dreaming.</p>
<h4><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fweighted_selector.rb&amp;rev=0&amp;sc=0" title="Stats">Stats</a></h4>
<p>This is a helper class that maintains minimum, maximum, and range stats for the last queued and rating data of tracks.  These stats are very useful in calculating normalized values.</p>
<h4><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fweighted_selector.rb&amp;rev=0&amp;sc=0" title="Weight">Weight</a></h4>
<p>This is a helper class that allows me to easily calculate, compare and debug the weights of different tracks, artists, or albums.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fschedule.rb&amp;rev=0&amp;sc=0" title="Schedule">Schedule</a></h3>
<p>The schedule class determines which ProgrammingBlock should be fed to the Selector.  It also provides the Mildred website with support in generating the <a href="http://www.xmtp.net/mildred/schedule/" title="Mildred's Schedule">Schedule</a> page, which displays the Schedule for a given date.</p>
<p>The Schedule loads itself from a <a href="http://www.yaml.org/" title="YAML ain't markup language">YAML</a> file.  The file describes which ProgrammingBlocks should be played at what times.  Any time a specific ProgrammingBlock is not specified, a default random block is used.  ProgrammingBlocks can be scheduled by start and end times, days of the week, days of the month, and months of the year.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Ftime_slot.rb&amp;rev=0&amp;sc=0" title="TimeSlot">TimeSlot</a></h3>
<p>The TimeSlot helps the Schedule determine which ProgrammingBlock to choose by allowing the current time to be compared to each of the times specified in the Schedule.  For example, the Schedule will load all of the ProgrammingBlocks.  It will then filter out those that aren&#8217;t eligible to be scheduled today.  Then, with TimeSlot&#8217;s help, it orders the remaining ProgrammingBlocks by start and end times.  Then it can iterate through the ProgrammingBlocks, and determine which one (if any) should be currently active.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Fprogramming_block.rb&amp;rev=0&amp;sc=0" title="ProgrammingBlock">ProgrammingBlock</a></h3>
<p>The ProgrammingBlock determines which artists, albums, or moods should be played.  Like Schedule, it is read from a YAML file.  ProgrammingBlocks also specify the probability of queueing a single track, an entire album, or a power block.  Many ProgrammingBlocks exist, but only one is active at a time, as determined by the Schedule.</p>
<h3><a href="http://www.xmtp.net/websvn/filedetails.php?repname=mildred&amp;path=%2Fmildred_rails%2Ftrunk%2Fapp%2Fmodels%2Ffetcher.rb&amp;rev=0&amp;sc=0" title="Fetcher">Fetcher</a></h3>
<p>The Fetcher is a simple utility class with one purpose, to load the actual Track objects specified in the ProgrammingBlock.  This means taking the artists, albums, and moods specified in the ProgrammingBlock, and returning a list of Tracks.</p>
<h3>The QBeat Loop</h3>
<p>The actual loop looks something like this:</p>
<ol>
<li>MpdMonitor checks to see if the currently playing track has changed, reporting the new track if it has</li>
<li>MpdMonitor checks the size of the MPD playlist
<ol>
<li>Selector picks a new track if the MPD playlist is too short</li>
<li>MpdMonitor adds the tracks specified by Selector</li>
</ol>
</li>
<li>MpdMonitor checks the size of the MPD playlist, and trims it if it is too long</li>
<li>QBeat sleeps for some amount of time (currently 10 seconds)</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://kill-0.com/duplo/2007/09/12/how-qbeat-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QBeat Visualization Fun</title>
		<link>http://kill-0.com/duplo/2007/08/10/qbeat-visualization-fun/</link>
		<comments>http://kill-0.com/duplo/2007/08/10/qbeat-visualization-fun/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 23:35:20 +0000</pubDate>
		<dc:creator>ericw</dc:creator>
				<category><![CDATA[mildred]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://kill-0.com/duplo/2007/08/10/qbeat-visualization-fun/</guid>
		<description><![CDATA[For mildred, I have a weighting system that determines which track to queue next. I call this system QBeat. I often try various tweaks to the algorithm for track weighting; trying and get that &#8220;perfect mix.&#8221; Debugging this system has proven to be a challenge, largely due simply to the amount of time it takes [...]]]></description>
			<content:encoded><![CDATA[<p>For mildred, I have a weighting system that determines which track to queue next.  I call this system QBeat.  I often try various tweaks to the algorithm for track weighting; trying and get that &#8220;perfect mix.&#8221;   Debugging this system has proven to be a challenge, largely due simply to the amount of time it takes to collect enough data to be able to determine if the system has any quirks.  With my current setup, it takes about 4 minutes to calculate the weight of every track in my collection (more about that in another post.)  So even queuing things as fast as possible isn&#8217;t always a feasible solution for data generation.</p>
<p>So to help me visualize is going with QBeat, I inserted a number of &#8220;tracers&#8221;, that is, tracks that report their weight every time a new track is added to the queue.  This should allow me to do some empirical testing of the system.  I really should be working further to develop better unit tests, but what the hell, this is fun.  <img src='http://kill-0.com/duplo/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So without further ado, I present the output from my viz_qbeat script:</p>
<p><a href="http://black.xmtp.net/~ericw/viz_qbeat_snapshot-2007-08-10-17-25.html" title="http://black.xmtp.net/~ericw/viz_qbeat_snapshot-2007-08-10-17-25.html">http://black.xmtp.net/~ericw/viz_qbeat_snapshot-2007-08-10-17-25.html</a></p>
<p>The link above is a static version of the page.  The live page is updated every five minutes by a cron job.  The X axis increments every time a new song is added to the queue.  The Y axis is the track&#8217;s weight.  The list at the bottom is each track, as it was enqueued.  A track&#8217;s weight rises proportionally with its likeliness of being enqueued.</p>
<p>So what can I learn from this static snapshot? Check out the medium blue line (&#8220;Cold Heart&#8221; by Project Pitchfork), which starts at a weight of approximately 2.6.  At around 38 on the X axis, its weight drops to 1.2.  Why did that happen?  Looking down through the list of queued tracks, we reach 38, and find that &#8220;Inquisition&#8221; by Skinny Puppy was queued at that time.  While &#8220;Inquisition&#8221; is not a track by Project Pitchfork, we can see that it is on an album titled <em>Industrial Beatdown</em>, and I happen to know that &#8220;Cold Heart&#8221; is also on that album.  So QBeat worked like it should.  Joy.</p>
<p>Here&#8217;s a link to the live site: <a href="http://black.xmtp.net/%7Eericw/viz_qbeat.html" title="http://black.xmtp.net/~ericw/viz_qbeat.html ">http://black.xmtp.net/~ericw/viz_qbeat.html</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Now playing: <a href="http://www.foxytunes.com/artist/tool/track/the+patient" title="'Tool - The Patient' - open on FoxyTunes Planet">Tool &#8211; The Patient</a><br />
<span style="color: #999999; font-style: italic; font-size: 10px">via <a href="http://www.foxytunes.com/signatunes/" style="color: #666666" title="FoxyTunes - Web of music at your fingertips">FoxyTunes</a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://kill-0.com/duplo/2007/08/10/qbeat-visualization-fun/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

