Programming and sewing

As someone who has been sewing since the age of 10 (that’s 20+ years) and programming Java since the mid-1990’s (yes I am old!), I am constantly amused at how similar the two activities are. In both practices, you are basically taking things apart and putting things together. Most people can envision how this works in sewing, but trust me, it’s not much different in programming. You put together smaller objects, like you would put together the pieces of a garment, and then you sew the objects together into a larger program. In sewing you finish off the edges so that things won’t unravel. In programming we do this by declaring final classes and static variables. In both you pick apart threads and you join threads together, which is never fun. OK the threads are already woven in sewing, but you still pick them apart sometimes. In both activities you have to patch things occasionally. In both we use patterns. These patterns are templates of how to do things to make something useful, and if the patterns are good, we use them again and again.

wedding-gown-sewing-pattern-194804112013_00002
A Wedding Gown pattern from the 1940s, from Vintage Patterns Dazespast Blog.

Finally, sometimes our sewing creations are a joy to create and turn out wonderful and useful, and sometimes they turn into a lumpy ugly mess that we spend lots of time reworking until we finally throw them away.

Can you think of other ways that programming and sewing are similar?

use lame to convert directory of .wav files to .mp3

If you use Ubuntu (or any other distribution of Linux) it can be surprisingly hard to convert a whole directory of .wav files to .mp3.

There is a utility called “lame” which works pretty well converting a single .wav file, i.e.:

lame filename

but who wants to sit there typing “lame” over and over again?

Oh sure, you could convert all the files using “find -exec” like this:

find . -name "*wav" -exec lame {} \;

But then you will find out how “lame” lame truly is! It leaves the “.wav” file endings, attaches a “.mp3” to them and this:

White Line 11-10-76.wav

becomes this:

White Line 11-10-76.wav.mp3

So you’d have to go through each file individually and remove the “.wav” ending as well as the spaces in the filenames!

Here is a better way. Though not perfect, it works. Each of these commands will execute on all files in the directory, so you only have to run each command once.

1. remove the spaces from the filenames:
find -type f -exec rename 'y/\ /\_/' {} \;

2. and get rid of the .wav from filenames*:
for file in *.wav ; do mv $file `echo $file | sed 's/\(.*\).wav/\1/'` ; done

3. Now run lame on the batch
find . -type f -exec lame -b 224 {} \;

Enjoy your .mp3 files!

* Step 2 is a little weird. After this step you are going to end up with files that have no file endings, but lame seems to recognize these as “.wav” files.

Use rowKeyVar to Access dynamic id from JSF dataTable using JavaScript

In JSF, ids of dataTable rows are dynamically generated. This can be frustrating when trying to access a specific field in a specific row from JavaScript. The trick to getting the specific dataTable field is to know the exact row number in JavaScript, and that is what I will demonstrate here.

I am using RichFaces 3.1.6 along with Apache MyFaces 1.1.3. For unexplicable reasons, I cannot get MyFaces 1.2.x to run with my Websphere Application Server Community Edition v. 2. So I’m stuck with 1.1.x. What this means is that I can’t use the newest version of RichFaces and I’m stuck with a lot of components that don’t work right.

I have a <rich:dataTable> with many rows, each of which contains several columns with <h:inputText> fields. A time value goes into each field and I need to validate the time input strings and compare them to one another.

I tried to use <f:validator>. Well it worked ok, but I couldn’t modify the javascript event that controlled the validation. It only responded to the “enter” key being pressed, and I wanted “onblur” to trigger the validation. Therefore I made a simple javascript call from within the <h:inputText> tag, like this:

<h:inputText value="#{addShopScheduleBean.sundayp2}" size="5"
id="sunp2" onblur="validateTime(this.value);">

I used ValidateTime like this, to validate a well-formed time string:

function validateTime(html) {
var match = /^([0-1]?[0-9]|2[0-3])\:[0-5][0-9]$/.test(html);
// empty string is ok
if ((!match) && (html.length > 0)) {
alert("BAD VALUE! ");
}
}

But, I need validateTime to do more. I need it to compare that field with another field in the same row.

JSF creates dynamic ids for all components, and the two id’s I needed were roughly:

‘a4jform-3:dt-173:0:sunp1’

‘a4jform-3:dt-173:0:sunp2’

The 0 refers to the row number. If I needed components from row 23 it would be:

‘a4jform-3:dt-173:23:sunp1’

‘a4jform-3:dt-173:23:sunp2’

It is this row number variable I needed JavaScript to have access to. Here is how I solved the problem.

I used the rowKeyVar in <rich:dataTable> like this:

<rich:dataTable headerClass="schedule" footerClass="schedule-foot"
styleClass="schedule" value="#{addShopScheduleBean.employees}"
var="schedshopemp" id="dt-173" rowKeyVar="myrow">

then, in my inputText, I called my javascript function, validateTime, using “myrow” as an argument:

<h:inputText value="#{addShopScheduleBean.sundayp2}" size="5"
id="sunp2" onblur="validateTime(this.value,#{myrow});">

Voila! My JavaScript can now see the row number from which it is getting called and I can get to the value of other inputTexts in that row, like this:

function validateLast(html, row) {
var lastval = document.getElementById('a4jform-3:dt-173:'+ row +':sunp1').value;
alert("html is " + html + " and row is " + row + " and lastval is " + lastval);
}

That enabled me to see what was in the ‘a4jform-3:dt-173:5:sunp1’. If for example I was in ‘a4jform-3:dt-173:5:sunp2’. Now I can compare the two entered times to see if the last one is earlier than the first and produce the appropriate errors for the user.

I hope this has helped someone.