Final Edition
February 27, 2009
On Contemporary Christian Music
February 23, 2009
Last December I attended an evening service at a local church. During that service a young teen-aged girl sang a song I generally really enjoy – Breath of Heaven by Amy Grant. The young girl had a phenomenal voice and excellent control. She sang beautifully, but there was something wrong and I couldn’t put my finger on what it was.
In my head I could hear Amy singing it and I compared. There was something about the maturity in Amy’s voice that was missing in the present rendition and suddenly I knew what it was. There is something in the act of singing that you can’t really put your finger on but your soul feels.
I can’t tell you why I knew. I can’t describe musically what was different. But I could feel a difference in attitude and in the mental state of the singer. The young singer lacked humility. The most magical part about Amy Grant’s version of the song is that somehow she captures the humility present in the story of Saint Mary. The young girl in the present wasn’t singing for the glory of God with an air of humility. She was singing to impress the audience.
I have been bothered by most contemporary Christian music for some time now but I couldn’t put my finger on why. Electric guitars and drums are not what bothers me. Not all contemporary music lacks humility, but 90% of what I hear does. It is not about bringing glory to God, but glory to the singer.
Next time time you listen, don’t just listen to the words, the tune, or the rhythm. Listen to the soul of the singer. For whom does he sing? You’ll hear it in his voice and know.
Lord, teach me humility.
Sheepology Visual Group Editor
February 17, 2009
I have been madly working on a visual group hierarchy editing tool to incorporate into Sheepology. I wanted to learn Flex and this was a great opportunity to do so.
You can view my work in the demo on sheepology.org. Just go to the Groups page and click on the Visual Group Editor button. At this time it is read only. It does pull data from the database initially to draw the graph, but changes made are not saved. You can drag a group onto another group to create a subgroup connection. It is still very rudimentary.
Here are a couple interesting observations.
It is very easy to embed images into a SWF using Flex. I particularly like the fact that I can embed vector SVG images created in Inkscape.
I had a hard time getting Flash remoting via AMF working between Flex and Django because I didn’t want to use the add-on packages the documentation described how to use. Instead I slogged through making an alternative method work that requires no additional packages and actually ends up being just as simple. I believe it does rely on using Flex 3.0 or greater though. Note that the DjangoAMF AMF gateway is set to ‘/amf/’ and the remoting service name is ‘groups’.
// connect remoting gateway
import flash.net.NetConnection;
import flash.net.Responder;
private var gateway:NetConnection = new NetConnection();
private function initApp():void {
if( Application.application.parameters.debug == 'True' )
gateway.connect('http::8000/amf/');
else
gateway.connect('http:/amf/');
initializeGroups();
}
private function initializeGroups():void {
gateway.call( 'groups.allGroups',
new Responder(
function(result:Array):void {
// success... do something about it
},
function(result:*):void {
// failure... handle error
}
}
);
}
Django Fun
February 10, 2009
I came across a cool Django tool called django-command-extensions that uses GraphViz to automatically generate a model graph of your application. Here is the graph I generated for Sheepology.
Check it out.
Sheepology Basics
February 10, 2009
There are a lot of details involved in the operation of a church. Those details will grow over time into Sheepology, but I wanted to identify the most basic fundamental structures and implement those first.
What I learned from experience volunteering in a church is that at the root of church structure are 3 things:
- People (individuals, families)
- Groups (ministries, serving teams, small groups)
- Events (Sunday services, small group get-togethers, team meatings, etc.)
This is how I organized Sheepology.
I’ve already talked about Groups, so let’s move on to People.
One of the key things I have done differently from most ChMS software I have seen relates to family membership. I had actually built this into my Perl-based check-in system several years ago and found that in today’s environment of divided families, it is very important.
A person can belong to more than one family.
This requires a slightly more complicated database structure (i.e. it’s a many-to-many relationship), but it is worth the extra complexity. There was one divorce situation I had to deal with repeatedly because the kids could not belong to both families in the ChMS. During check-in, the father would always attempt to use his phone number or name to check in the kids, but they would not come up. I had to explain that I had no control over the system and explain what information to use when checking in. I think he resented the fact that our database could not recognize his fatherhood of the children.
The other unique feature I wanted to add was an embedded webcam tool for taking photos of individuals. Try it out in the demo, it works. Additionally, if the individual does not have a photo, Sheepology will automatically attempt to use a Gravatar.
Eventually I would like to do something with Facebook integration.
Sheepology and Trees
February 8, 2009
First, I want to clarify what I said in a previous post. I said there are 2 ways to organize people, groups and tags. What I failed to mention is families. I originally considered making a family just a special case of a group, but I decided in the end that families are such a special and important group that it needed to be it’s own special construct. At one point I considered making Sheepology into a full-fledged genealogy system as well, providing ways to traverse trees of relatives, find cousins, etc. What I decided in the end is that it would be pointless to the operation of a church and just add unnecessary complexity.
On to trees…
The difference between a general graph and a tree is that a tree has no loops. The danger in allowing loops in your structure is that the methods I demonstrated in an earlier post could potentially run forever (though Python raises an error if you reach its maximum recursion depth, and of course you would eventually run out of memory). So in order to simplify things and actually have them make sense you need to prevent loops from occuring, ensuring that your structure always remains a tree.
So I extended my Group form to check for loops before validating:
def clean(self):
for g in self.cleaned_data['groups']:
if self.instance == g or self.instance in g.getSubgroups():
raise forms.ValidationError('Recursive Group structure detected.')
return self.cleaned_data
Where getSubgroups() looks like:
def getSubgroups(self):
'Get all subgroups of this group.'
for group in self.groups.filter( active=True ):
yield group
for subgroup in group.getSubgroups():
yield subgroup
Sheepology and Church Structure
February 7, 2009
Many church management systems I have seen are what I would call unnecessarily complex. They start out with a special structure for ministries and then under that have special structures (and interfaces) for groups, sub-groups, staff groups, etc. The interface becomes unwieldy, unintuitive, and basically requires a manual sitting next to you to use correctly.
To top it off, if you want to make a report of who showed up to what event and belonged to such-and-such a sub-group of X ministry and Y group, you almost have to write a custom report. This tends to produce a system in which you basically need a Google-level search engine just to find a report that will work in your situation.
Sheepology has 2 ways of organizing people: Groups and Tags. Tags you all know and love. They are a quick and dirty way to organize things. The danger in tags is that you can get too many words that mean the same thing and your staff have to voluntarily comply with a standard tagging scheme if you want to use them to organize your structure. Tags are best as an informal quick-and-easy way to visualize your body and keep track of nice-to-know aspects of an individual (or group), i.e. skills like cooking, skiing or running.
What all the different layers of structure in an organization boil down to is a classic tree structure. You have nodes and connections between nodes. Why make it more complex than that?
Basically a Sheepology Group contains people and other Groups (and of course meta-data like name and description). You can have a tree that goes down 42 levels deep if you want. You can have as many top-level nodes as you want. You can basically have multiple inheritance if you want. One Group can be contained by as many parent Groups as you like.
So suppose I want to find all the subgroups of a particular group? The Group class has a simple recursive method called getSubgroups. This method returns a python generator (i.e. it acts like an iterator):
def getSubgroups(self):
'Get all subgroups of this group.'
for group in self.groups.filter( active=True ):
yield group
for subgroup in group.getSubgroups():
yield subgroup
Or suppose I want to find all events that members of group X can check into.
def getCheckableEvents(self, **kwargs):
'Get all events for which people in this group may be checked in.'
for event in self.events.filter( checkin=True, active=True, **kwargs ):
yield event
for group in self.parent_groups.filter( active=True ):
for event in group.getCheckableEvents( subgroup_checkin=True ):
yield event
Sheepology and IE
February 6, 2009
BTW, I don’t even know if Sheepology works in IE. Haven’t bothered to check. For now use Firefox.
More on Sheepology
February 6, 2009
At the Rocky, we were beginning to create a number of geographically oriented applications (see our Holiday Lights). Lucky for us, GeoDjango had been recently rolled into the official release of Django. By simply installing the PostGIS extension to PostgreSQL, we had built-in geographic proximity search and much more. Here’s a sample that finds all addresses within 5 miles of the current address:
nearby = Address.objects.filter( point__dwithin=(self.point, D(mi=5)) ).exclude( id=self.id )
if len(nearby) > 0:
raise SomeException('Uh Oh...')
This type of feature not only makes it easy to find people who live near each other (presumably by small-group staff), it allows for improving data quality. When storing an address in the database, you can check to see if there is a likely duplicate (i.e. an address that is within a meter or so of another address) and prompt the user for an override if necessary. I have built this into Sheepology.
Something I have always been interested in is AI and natural language processing. So I was somewhat interested in making searches more fault tolerant. One problem we had at Crossroads was that we ended up with a lot of duplicate people in our database because searches failed. I wanted to improve the situation. I did a little reasearch and discovered an algorithm called soundex. While many databases have this built in, they do it on the fly, so doing a search becomes very slow. I decided to simply make an extra field that contained the soundex codes for people’s names. This way I am able to index the field and make the search fast. Python has a module called AdvaS that has the soundex algorithm and several other similar algorithms. So in just a couple lines of code I was able to have phonetic search. Try it in the demo if you want. Search for bryan and you’ll find brian as well. Or search for sherri and you’ll still find shari. In the main settings file you can choose your phonetic algorithm, but it defaults to soundex.
There is also a nice tagging module available for Django. It was remarkably easy for me to plunk this in and magically have tagging enabled on models I chose. In about 5 lines in my template I was able to create a tag cloud.
I had originally decided to develop my own UI for Sheepology, but decided to work on building the basic models first. What I found is that the built-in Django admin facilities are so extensible, that I may stick with the built-in admin rather than building a UI from scratch. I also added the Grappelli theme to jazz it up a bit. While I’d like to take credit for the look of the admin, for the most part it is a packaged theme designed by someone else.
What I have found with Django and Sheepology is that I am most effective as a systems integrator. While I have written a fair amount of custom code, what I am really doing is tying together a number of different open-source pieces to make a whole package. I can focus on my area of expertise (i.e. churchy stuff) and worry less about details.
I was able to build what you see as a one-man team in about 2 months. What I see down the road is nearly limitless. There are a number of Django open-source packages for doing such things as content management or accounting that could potentially be integrated into Sheepology for a comprehensive ChMS package.
On the immediate horizon I will be working on a graphical group hierarchy tool. I also see a need for an inventory tracker (portable churches desparately need this) and contact management.
Sheepology Demo
February 5, 2009
There is now a live demo of Sheepology.
The Story Behind Sheepology
February 4, 2009
About 7-8 months ago I decided to resurrect the check-in system/church management system I wrote about many moons ago. I did go back and look at it and decided that while it had some good features, it wasn’t worth keeping. I shopped around for a good platform on which to build (this was about the time Google announced AppEngine). This announcement made me more aware of Django than I had been before and gave me reason to believe that Django was going places. I had always been curious about Python so this was a good match. I also considered Ruby on Rails and Catalyst for Perl, but decided that with Google behind Django, Django would be a good choice. I was also considering a move to Colorado and had recently seen a Django job that sounded interesting (the job I currently have).
I had recently begun using jQuery at my previous job and really liked it. I had toyed with Mootools a bit and decided I liked jQuery better. A coworker had tried several others including Prototype and decided jQuery was best. I trust his judgment so I stuck with jQuery. This was a lucky turn of events because the Rocky uses jQuery too.
So I began writing a system. I worked on this for about 2 months and then applied to the job (which was still available). I got it and moved out here. I forgot about my project for a while until I heard the announcement that the paper was up for sale. At this point I was crushed. I loved this job. I also realized that someday I want to be financially independent. That brought my project back to the forefront.
A newspaper environment can be very intense! I created more tables in a database in 3 months at the Rocky than I did in 12 years at Mathematical Reviews. I wrote a lot of code in 3 months and learned Django very well. I went back and looked at my project and decided to throw it out for the most part and start over.
Now that I’m looking for a job I find that while Django is a hot new growing technology, there are not a lot of Django jobs in metro-Denver. Bummer. I need to enhance my resume some more so I decided to try out Flex. The Rocky uses Flex and we have a flex developer in-house, so I got to use him as a resource (he likewise used me as a Django resource). I wanted to be able to use a webcam directly in my application for taking photos, so I wrote a little Flex app to do so. My next Flex project is an interactive graphical interface to the groups system – sort of a dynamic drag-and-drop org-chart.
The name started out as Soma – Greek for body. That just didn’t have a good ring to it. I tried Corpus – Latin for body – which sounds cool but doesn’t seem memorable. I finally landed on Sheepology. It feels sorta “web 2.0″ and catchy. A bit long perhaps, but it will do. (It also gave me an excuse to design some 3D sheep in Blender).
More on the design of Sheepology to come…
Software Developer for Hire
February 4, 2009
About 5 months ago I moved to Colorado and started work at the Rocky Mountain News. Two months ago the parent company announced that they were putting the Rocky up for sale as it lost about $15,000,000 last year. So I started job hunting.
The paper has not yet closed and I am still looking for the right job. My plan is to stay in Colorado somewhere along the front range.
If you’re interested, check out my online resume.
Sheepology
February 3, 2009
I have been silent for quite some time. I’m back. Here’s what I’ve been working on recently.
More to come…
