February 25th, 2008 benhughes
As a (wannabe) Jazz pianist, I’ve always had a strong interest in Jazz theory not only from a practical you-need-this-to-play standpoint but also a theoretical standpoint. At it’s core, music theory is all about a 0 - 11 number system where each number represents a pitch, with the added complication of letters (which makes Eb theoretically different from D#). Everything in music is based on this basic number system: scales and chords are simply sequences of these numbers. Changing key in a scale or chord mathematically is adding some integer to all of the index values and doing modulo 12. Changing modes within a scale simple involves a position shift of the sequence.
Last week I began exploring the idea of developing some sort of computerized object model to capture these musical theory concepts. As a pianist, knowing theory is extremely important and voicing chords can become quite complex, yet there is sanity in the complexity - a harmony of mathematical precision. Today I introduce “Jazz Toolbox”, the future front-end for which will be located at JazzToolbox.com. Right now I have only developed the back-end object model and calculation engine, which is definitely the foundation of the project. I’ve also written up extensive documentation. Here’s an introduction to the project straight out of my README file:
Jazz Toolbox
Jazz Toolbox is an online Jazz utility driven by a full object-relational and REST model of
concepts in Jazz theory, establishing relationships between chords and scales, and much more.
The web interface is a fully Ajaxified Web 2.0 interface towards exploring these relationships and
answering questions about the jazz science. The REST interface exposes the underlying data model
and relationships to other developers wishing to use Jazz Toolbox as a source for their own web
applications.
Architecture Overview
The core of Jazz Toolbox is a full Ruby object model representing concepts of Jazz theory,
distilled to their most basic concepts and architected in a very abstract manner. The system
is data-centric and all “rules” (for example, the tones in a C7 chord) in theory are
self-contained in the database.
All chord/scale/mode/etc. definitions are stored as a mathematical system (sequences of numbers)
which are then used to perform calculations. For example, putting some chord in a different key
is a matter of adding a semitone delta and doing modulo 12.
While there are currently many chord calculators in existance, to my knowledge this project is the
first one that attempts to fully represent the entirety of Jazz theory as a mathmetical/computational
system exposed through an elegant object model.
Full Documentation
I’ve published the full RDocs which are available here and are very complete.
Examples
Any musician/programmer will appreciate these examples; far more are available in the rdocs:
Chord['Ebmaj7'].notes
# => ['Eb', 'G', 'Bb', 'D']
# Or specify key context with chained methods like this...
Chord['maj7'].in_key_of('Eb').notes
Chord['Bmaj7#11'].notes
# => ['B', 'D#', 'F#', 'A#', 'E#']
# Note E# - Correct theoretic value for this chord, not F
Chord['Falt'].notes
Chord['F7b9#9'].notes
# => ['F', 'A', 'Eb', 'Gb', 'G#', 'C#']
Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
# => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']
Scale['Melodic Minor']['Lydian Dominant'].notes
# => ['F', 'G', 'A', 'B', 'C', 'D', 'Eb']
Scale['Major']['Dorian'].chords.symbols
# => ['min7', 'min6']
Chord['Amin7'].modes.names
# => ['A Dorian']
Scale['Major'][4].chords.symbols
# => ['maj7#11']
This is definately still a work in progress though it has the potential to become very powerful. I have high ambitions for the front-end web interface for this as well as it could become a valuable tool for Jazz musicians and others trying to nagivate the complex roads of jazz…
Posted in Uncategorized | 2 Comments »
February 21st, 2008 benhughes
Occassionally I’ll decide to create some structured data in a migration by issuing create statements against my model classes. In a project I’m currently working on, I had to do this several levels deep. Rather than using temporary variables to create the sub items and so-on, all in a lexically flat structure, I came up with this simple one-liner:
def self.with(o); yield o; end
Doing this now allows me to issue those creates with nested data as a series of nested blocks, which is looks much better. For example:
with ChordQuality.create(:name => 'Major', :code => 'MAJ') do |q|
with q.chords.create(:name => 'Major Triad') do |c|
c.chord_symbols.create(:name => 'maj')
c.chord_symbols.create(:name => 'M', :case_sensitive => true)
end
with q.chords.create(:name => 'Major 7') do |c|
c.chord_symbols.create(:name => 'maj7')
c.chord_symbols.create(:name => 'M7', :case_sensitive => true)
with c.children.create(:name => 'Major 7 #11') do |cc|
cc.chord_symbols.create(:name => 'maj7#11')
cc.chord_symbols.create(:name => 'M7#11')
cc.chord_symbols.create(:name => 'lyd')
cc.chord_symbols.create(:name => 'lydian')
end
end
with q.chords.create(:name => 'Major 6') do |c|
c.chord_symbols.create(:name => 'maj6')
c.chord_symbols.create(:name => 'M6', :case_sensitive => true)
end
end
Oh, the beauty of Ruby code blocks!
Posted in Uncategorized | No Comments »
February 7th, 2008 benhughes
Since working with Ruby and other dynamic languages, I’ve thought a lot about the differences between statically-typed and dynamically-typed languages and what makes them different. Statically-typed languages guarantee some level of confidence of workability — but this comes at a huge cost of flexibility, and more importantly overlaps with software testing, not making efficient use of the concept of testing.
Software testing can be used to make up for some of the lost confidence resulting from dynamic typing, yet since they must be done regardless, the outcome is suboptimal with static languages - there is an overlap between the confidence generated from static typing and the confidence generated from the test suite. With dynamic languages there is much less overlap: the test suite makes up for the confidence lost from dynamic typing, yet is also there to ensure the software works as expected.
Posted in Ruby Evangelism, Ruby Language | No Comments »
February 2nd, 2008 benhughes
ActiveRecord::Base exposes a great way of keeping access control DRY. A very common paradigm in web application development is showing “all” of something to administrators but only only “active” of something to regular users/visitors. In non-ORM PHP you might do something like like this in each SQL statement:
$sql = "SELECT * FROM entries WHERE type = 1 ";
$sql .= (!$is_admin ? "AND active = 1" : "");
This isn’t a very well-architected approach since this type of tacking onto the SQL string would have to be done in any statement that involved this table, for all of your “actions” like show, edit, and index. It tightly couples this particularly piece of add-on logic to your base code. In Rails we can scope out this functionality to a “scope_access” method in our controller like so:
class EntriesController < ApplicationController
around_filter :scope_access
# (Action Methods)
protected
def scope_access
unless current_user && current_user.is_admin?
Entry.send(:with_scope, :find => {:conditions => 'active = 1'}) do
yield
end
else
yield
end
end
end
We are declaring an around_filter which uses with_scope if the current user is an admin, otherwise it will do so without scope. This is an excellent example of how Rails allows you to architect your code to be very elegant. Note that with_method is now a protected method on ActiveRecord::Base hence our need to use ClassName.send.
The with_scope method is actually useful for many other purposes including running many but similar find statements. Aside from finders, this can actually scope attributes on create and more. I’d highly recommend you check it out in the Rails documentation and start making extensive use of it.
Posted in Uncategorized | 2 Comments »
February 2nd, 2008 benhughes
Antagonistic attitudes towards Ruby and in particular Ruby on Rails abound. Many web developers feel uneasy about the rise of a strange new framework that is attracting disciples daily. I’ve casually chatted with a few people who have negative attitudes about Ruby and the most striking aspect about everyone I’ve spoken with is that after prodding a bit at their understanding and experience level with Ruby I find they only have a surface-level understanding of Rails and no experience whatsoever. I have not once found someone who was well-versed in both Ruby on Rails (as in.. has actually built an application using it) and in any of the other number of web technologies out there, who was not at the very least appreciative about Rails and optimistic about its future.
What I’m trying to get at here is that to appreciate Ruby you have to know Ruby, and know it well. A surface-level examination of Rails by myself over one year ago left me in the same ignorant state that many Ruby antagonists are at right now, complaining about Ruby’s ability to scale and the restrictive nature the Rails framework involves. Even reading a few chapters out of the Agile book might leave one with this characterization. Yet the more I began to understand Rails and even more importantly the dynamic Ruby programming language, the more positive my attitudes towards Rails were.
It’s interesting that I find this particular understanding imbalance even more widespread and frustrating in economics: to appreciate the free market, you have to understand the free market. So few people truly understand economics and as a result their arguments are ripe with economic fallacies and mischaracterizations of fact. Economists on average believe that the free market works significantly better than non-economists. This isn’t a conspiracy: it’s because they actually understand economics.
There will always be people in any field that attack something they don’t understand for whatever reason. Those making arguments against Rails at least owe it to their opponents to actually understand what they are talking about. I find such is rarely the case.
Posted in Ruby Evangelism | 3 Comments »
February 2nd, 2008 benhughes
Until now I’ve been running a my personal sites and a few other random sites I host on a dedicated box running CentOS 4 and Plesk. Last week I took the plunge for a SliceHost VPS and decided to configure everything myself and try to squeeze it all on a 256MB slice for $20/month. Although there isn’t anything specifically about SliceHost that makes it well-suited for Rails hosting (after all, it’s just a Linux VPS - put whatever you want on it), the SliceHost guys are Rails developers and the documentation available on articles.slicehost.com is geared towards Rails production environments.
I wanted to use the switch as a learning experience with setting up a cluster of mongrels behind Apache 2.2, a setup I’ve never tried before. I’ve used FastCGI with Apache and Nginx proxying to mongrel clusters, but I was looking for a more powerful setup using Apache as the front-end web server. So I configured Apache 2.2 (with the Debian layout, much different than the “conventional” layout) with mod_proxy_balancer and PHP. MySQL and Apache were fine-tuned to run with the smallest memory footprint that is practical. Apache is proxying to a cluster of mongrels hosting BenHughes.name (which will eventually be a larger site) and a new Facebook application I’m currently developing.
To reduce the memory requirement, and because I find it a better piece of software, I switched this blog and my economics blog to WordPress running as PHP within Apache. I toyed with the idea of keeping these on Typo and Mephisto, respectively, and running them with just one mongrel instance, but doing so would really eat up my memory on my 256MB slice quickly. WordPress is pretty nice and has a much larger community of people developing themes.
I also moved my two Subversion repositories over (one private, one public and yet to be used: http://svn.railsgarden.com/). Previously I was hosting DNS and E-mail which was just a hassle, so I decided to switch all of my domains to Google Apps and host the DNS at SliceHost, maintainable through their management portal.
I have to say I’ve been exceedingly happy with SliceHost thusfar - their management portal is simple and to-the-point with no BS. They have dedicated resources and do not oversell. $20/month for what I’m getting is a pretty darn good deal - it feels good to continue having root on my own Linux system out there in a data center. Hell for $20/month a VPS is a great way to just fool around with and learn with. I may get another slice just for that purpose.
Posted in Personal | 2 Comments »