Very simple Bash script to get source code stats


Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 1827

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 1827

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 2180

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3025

Warning: implode() [function.implode]: Argument must be an array in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3077

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3108

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3108

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3151

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3151

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3292

Warning: Invalid argument supplied for foreach() in /home/.mokey/tripu_admin/www/blog.tripu.info/wp-content/plugins/wp-syntax/geshi/geshi.php on line 3292

The other day I wanted to have an overview of the size of a software project I’m working on. The project is relatively big and involves quite a few languages and technologies spread among different tiers. Because I just joined the team there are tons of lines of code already written that I have not even seen. So I felt the need to have at least a grasp of the size of the codebase for each language and learn how programming languages compare among them within the project.

I came up with this very simple Bash script, getSizeStats.sh. It expects one or more directories as parameters. It finds all regular files contained in the trees that hang from those directories. It then adds up LOC for all files, grouping by the extension of the filenames. The script assumes that the arguments are, or might be, local copies of Subversion repos (that’s why it excludes .svn directories). While running, the output line shows a counter for the number of files as they are processed. Once finished, a list of LOC for each language (i.e. file extension) sorted by LOC is created in /tmp/getSizeStats.sh.out.

#!/bin/sh
 
TMP_DIR=/tmp/`basename $0`
TMP_OUTPUT_FILENAME=/tmp/`basename $0`.tmp
OUTPUT_FILENAME=/tmp/`basename $0`.out
 
if [ -d $TMP_DIR ]; then
    rm $TMP_DIR/* 2> /dev/null
else
    mkdir $TMP_DIR
fi
 
COUNTER=0
 
find "$@" -name "*.*" | grep -v \.svn | while read j; do
 
    if [ -f "$j" ]; then
        cat "$j" >> $TMP_DIR/`echo $j | rev | cut -s -d "." -f 1 | cut -d "/" -f 1 | rev`
        COUNTER=$((COUNTER + 1))
        echo -en "\r$COUNTER files "
    fi
 
done
 
if [ -f $TMP_OUTPUT_FILENAME ]; then
    rm $TMP_OUTPUT_FILENAME
fi
 
for i in `ls $TMP_DIR`; do
    echo -e "`wc -l $TMP_DIR/$i | cut -d " " -f 1` $i\t`wc -l $TMP_DIR/$i | cut -d " " -f 1`" >> $TMP_OUTPUT_FILENAME
done
 
sort -nr $TMP_OUTPUT_FILENAME | cut -d " " -f 2- > $OUTPUT_FILENAME
rm $TMP_OUTPUT_FILENAME
 
echo processed -- see $OUTPUT_FILENAME
 
# EOF

(I think that for some versions of echo you’ll have to remove the option -e or it won’t work properly).

The only serious problem I found were filenames containing blanks and other characters that usually need to be escaped (bad naming, I know — it wasn’t my idea). I played with different types of quoting and tried to find a workaround for that. Real-time help about that from @enlavin and @nauj27 was much appreciated. I tried that find -print0 | xargs -0 … thing but couldn’t make it work as I needed. Eventually the while read j; do … approach worked. (I confess that I still get confused easily by the subtle differences between quoting variants and how variables get expanded in each case. I ought to find some time to learn that well, once and for all).

Now there are so many things to improve here. First of all, the script does not tell binary files from text files, i.e. you will also get counts of “lines of code” for all binary assets within your project, such as object files and images. It should also discard all text files that are not source code, e.g. a CHANGELOG. It should be robust to case variations, i.e. group .java and .JAVA files together. It should rely on something more sophisticated than filename extensions to tell programming languages, because you probably want to count your .cpp and .c++ files as a whole.

I was planning to better it adding those fixes/improvements and others. Then Golan told me of sloccount, a command that does just what I need. But proper.

Here you have an example of how getSizeStats.sh works. After re-inventing the wheel, I couldn’t but run my own script… against the source code of sloccount itself.

$ svn co https://sloccount.svn.sourceforge.net/svnroot/sloccount sloccount-src > /dev/null
$ ./getSizeStats.sh sloccount-src/
38 files processed -- see /tmp/getSizeStats.sh.out
$ cat /tmp/getSizeStats.sh.out 
c       4493
orig    3899
html    3032
1       235
dat     197
l       171
rb      152
lhs     59
spec    56
h       50
CBL     31
php     27
inc     23
pas     21
hs      19
gz      10
f       10
cs      8
f90     7
cbl     4
tar     1

11 May 2008 2 comments so farComputers


Un poco de ciencia

Teorema Del Ánimo Inducido:

«Para cualquier grado de cansancio acumulado c, hora intempestiva h y tarea importante e inaplazable t existe al menos un par {e, v} con e estilo de música y v volumen que hace t soportable.»

Conjetura Del Masoquista (no demostrada):

«Además, siempre existe al menos un par {e, v} que hace t placentera.»

Teorema De Friquismo No-Anulable:

«No importa cuan grandes sean c y h, siempre es posible encontrar al menos una parida p que necesite ser blogueada antes de acometer t

7 May 2008 5 comments so farLife, Music


Power of programming languages

The fact that all these [programming] languages are Turing-equivalent means that, strictly speaking, you can write any program in any of them. So how would you do it? In the limit case, by writing a Lisp interpreter in the less powerful language.

That sounds like a joke, but it happens so often to varying degrees in large programming projects that there is a name for the phenomenon, Greenspun’s Tenth Rule:

‘Any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp.’

If you try to solve a hard problem, the question is not whether you will use a powerful enough language, but whether you will (a) use a powerful language, (b) write a de facto interpreter for one, or (c) yourself become a human compiler for one. […]

This practice is not only common, but institutionalized. For example, in the OO world you hear a good deal about ‘patterns’. I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I’m using abstractions that aren’t powerful enough — often that I’m generating by hand the expansions of some macro that I need to write.”

Paul Graham, “Revenge of the Nerds”.

23 Apr 2008 No comments yetComputers


Cuatro razones para estar contento

Una revelación de optimismo repentino que me vino esta tarde, de ésas que conviene atrapar y archivar pa’ cuando hagan falta:

  1. Por las mañanas tardo exactamente veintidós minutos en llegar desde casa a mi nuevo trabajo; tres paradas de metro sin transbordos más dos paseos muy cortos. Al mediodía puedo andar cinco minutos y comerme el bocata en el «Km 0» de Londres, sentado en las escaleras de la National Gallery, al pie de la Columna de Nelson.
  2. Por las tardes, después del trabajo, sólo tengo que caminar otros diez minutos para llegar a la escuela de idiomas en la que hago mi curso para ser profe de español: un par de manzanas hacia el norte, cruzo Covent Garden justo por el centro de la plaza y enseguida llego a Holborn. Si me pongo tonto alargo el paseo un minuto o dos más y atravieso también Seven Dials, un barrio que me encanta.
  3. Mi nueva empresa es muy solvente y ofrece todas las facilidades típicas de una organización con casi 200 empleados en Central London. Me pagan más que en mi trabajo anterior, en principio trabajando igual o menos. Y los horarios son medio flexibles. Parece casi seguro que no voy a tener problemas para ir a clase cada tarde de lunes a jueves.
  4. Desde que cambió la hora, salgo del trabajo y aún es de día un buen rato.

Hago lo que me da la gana con mi tiempo. No dependo de nadie y nadie depende de mí.

15 Apr 2008 7 comments so farLife


Londres-Bruselas HOWTO

Esta tarde cojo el Eurostar de nuevo, esta vez para ir a Bruselas 48 horas, a pasar el finde con el Sr. Zugaldía. Los objetivos de la misión son estos, y en el siguiente orden:

  1. Aprovechar lo raro que es que podamos coincidir en el mismo punto del espacio-tiempo y ponerme al día con Z. Tomar algo, arreglar el mundo, charlar de todo un poco. Retomar la polémica “Londres vs Bruselas” y hacer ver a Antonio de una vez que Londres es la capital de Europa, mientras que Bruselas, si se esfuerza, podría llegar a la categoría de digna localidad de provincias }:¬D
  2. Probar el plato típico local, que es… mejillones con patatas fritas (Z dixit!).
  3. Ver si aún encuentro algo de la nieve que cayó en Bruselas hace una semana.
  4. Fotear la versión femenina del Manneken Pis, que no vi cuando pasé un día en Bruselas hace años.
  5. Vivir peligrosamente y sentirme al otro lado de la ley haciéndole fotos al Atomium y subiéndolas después a Flickr sin pedir autorización.

Por si alguien más está interesado en escaparse a Bruselas un fin de semana desde Londres, detallo los pasos a seguir:

  1. Ir a http://eurostar.com.
  2. Hacer clic en “United Kingdom”.
  3. Seleccionar Londres-Bruselas-Londres y un fin de semana cualquiera.
  4. Seleccionar la combinación más barata.
  5. Extrañarse de que éso sea “lo más barato”.
  6. Volver a http://eurostar.com y entrar esta vez por el lado belga, haciendo clic en “Belgium” (tendrás que borrar las cookies).
  7. Seleccionar el viaje inverso (Bruselas-Londres-Bruselas) para el mismo fin de semana, en la combinación más barata.
  8. Calcular el cambio de moneda y comprobar con indignación que cuesta entre un 30% y un 40% menos.
  9. Maldecir un poco (en inglés o en francés, esto da igual).

En realidad no importa que entres por el lado insular o por el continental. Lo que cambia tanto el precio es el sentido del viaje de ida y vuelta (aunque con el cambio actual de divisa, el mismo viaje es más caro reservándolo en euros que en libras). Si uno vive en Londres y tiene que viajar en Eurostar al menos unas pocas veces al año (por ejemplo, por motivos de trabajo) sale más barato comprar el primer viaje suelto, y luego ir cabalgando idas y vueltas como vueltas e idas.

28 Mar 2008 One comment so farLife


Sex in Japan

For all Japanophiles out there: via @esole I found the other day a very instructive post entitled “Sex and flirting in Japan” …that talks exactly about what its title says, from the perspective of a foreign girl living in Japan (and flirting and having sex with Japanese guys).

The post is especially interesting because it’s not PC, but rather a bit “mean” and explicit (and funny). It explains the Japanese very special way of understanding relationships between men and women, and sex (mojigatos, stay well away from this post).

Having visited Japan once myself, and being very curious about Japan and the Japanese, I can relate to most of what supacat is telling here (although I didn’t have any experience in that particular field and my mindset during those two weeks was not that ;¬) You don’t need to flirt with a Japanese girl to notice that women in Japan are passive and submissive — to extents that shock us Westerners and even make us feel embarrassed. You don’t need to have sex with natives to understand that there are rules always. You can feel rules floating around in every interaction with other humans, and personal spaces tend to have very large radii.

So if you thought that Japan is further away than Mars (it is further away than Mars) go and read this. Shocking, to say the least. And IMHO not very appealing :¬(

If after this you still want to visit Japan, don’t miss Kirai’s ten tips for a trip to Japan (in Spanish).

[Note: right before hitting the “publish” button I double-checked my links and… the post is gone :¬( Looks like supacat just decided to remove it. It's a pity. Good news is, it was online long enough to get tweeted, reddit'd and digg'd, so you might be able to find it pasted or cached somewhere…]

27 Mar 2008 3 comments so farJapan


Segundo aniversario

Mañana («hoy», en realidad) hará exactamente dos años que vivo en Londres (¡dos años, ya!). Hace días que lo apunté en RTM para acordarme de hacer repaso y compartirlo con vosotros aquí hoy. Como ya hiciera hace un año.

Pero en estos días me rondan la cabeza bastantes más cosas. Trabajo, otras actividades y algún cambio; ya os contaré. Las últimas semanas han sido intensas, y las que se avecinan van a serlo aún más. Hoy trabajé hasta tarde, llevo cansancio acumulado y debo dormir unas horas. Porque mañana me voy cuatro días a Escocia con PabloBM, Golan y Rosario :¬)

Así que de momento, paso de escribir sobre mi aniversario. Ya resumiré mis impresiones de estos dos años a la vuelta, si es que veo que tengo algo medianamente interesante que compartir.

Estaré en analógico total durante los próximos cuatro días (no llevo portátil y mi teléfono es un dumbphone). Unas 96 horas sin hacer Ctrl+R ni ⌘R en ninguno de los quince mil sitios, servicios y comunidades en los que “vivo”. Eso para mí equivale a una eternidad larga.

Pero me va a venir bien despegarme del teclado; aunque sea a la fuerza, pardiez.

Pasad un gran fin de semana.

20 Mar 2008 One comment so farLife


Adobe Flex in 10 minutes

If you are a software developer, a web designer or some other sort of techie it’s very likely that you have been hearing and/or reading about Adobe Flex lately. Well, if you aren’t using it yourself but feel curious about it, or if you just want to have a notion, this extremely quick introduction is for you. Skimming through this post will not turn you into a Flex developer, but it will allow you to nod confidently and even drop some canny words the next time that Flex pops up in a conversation around the watercooler.

First things first — what Adobe Flex is not:

  • It is certainly not a tool for generating lexical analysers ;¬)
  • It’s not “the new version of Flash” (FKA “Macromedia Flash”). Development of Flash is on-going and the two products coexist. Flex hasn’t replaced (and won’t replace) Flash anytime soon, the reason for that being that…
  • …Flex is not “an alternative to Flash”. Sorry to disappoint you, but Flex is not a way to get rid of the dependence on the Flash Player. Actually Flex is built on top of Flash and needs Flash Player to run.
  • It’s not a technology to build large, native apps that need to work close to the underlying platform or which performance needs to be optimised (read below to see why I believe this).

Flex in a nutshell (a rather small nutshell):

Flex is an attempt by Adobe to make Flash attractive to, and suitable for, many software developers who were disregarding Flash as something not serious enough to use for developing “proper software”. Adobe has done a praiseworthy effort in that sense and has brought Flash to the realm of OO programming. Adobe used Eclipse to develop Flex Builder. Flex Builder alone does a lot to make old-skool software developers feel at home — it’s a proper IDE with all the features you would expect, plus the extensibility (and the slowness, I’m afraid) of Eclipse.

Flex developers use the Flex SDK (command line compilers and component class library; free as in “freedom”) and the Flex Builder (the IDE) to build their applications. Flex apps are written mainly in two languages:

  • Actionscript, an ECMAScript-based language that exists since the first Flash Player.
  • MXML, a loose, proprietary implementation of XML used to define GUI elements.

The output of a Flex project is one or more Flash files (.swf). In terms of the approach to the development process, the single most important change from Flash to Flex is probably removing the “movie” way of thinking. Flash animators are used to the “movie paradigm” in which the time is an essential concept. In their animations they have been working with key concepts like “timeline”, “frame” and “loop”. Flex abandons that approach.

I have found that, in general, software developers without any experience with Flash get used to Flex even faster than Flash designers who don’t know much about programming.

What Flex is good at:

  • Rendering cool interfaces. Animations, transitions, effects, gradients, reflections, customised skins, embedded movies, nice charts, changes in opacity, layouts that are resized well when their container is resized, etc. For a demo, check the Flex 2 Component Explorer.
  • Working on all major desktops and web browsers and many mobile devices. OS’s: Windows, Mac OS, Linux and Solaris. Browsers: IE, Gecko-based browsers, Safari, Opera. Mobile devices: many, and more to come.
  • Keeping the same “look & feel” everywhere. You can see the default Flex 2 “look & feel” in the Flex 2 Style Explorer.
  • Integrating and communicating with other Adobe formats. Flash movies, Acrobat documents, ColdFusion, Dreamweaver, etc.

What Flex is not good at:

  • Computationally expensive software. As we saw before, Flex stresses GUI aesthetics, intuitive design, portability, compatibility with existing Flash files and other Adobe tools, easy deployment, etc. And it was aimed at the web (in spite of Air). So don’t expect it to be any good at doing system calls, invoking hardware drivers, messing with the network at low-level, fine-tuning loops to save cycles of CPU, dealing with gigabytes of data, delivering real-time, etc. Because Flex apps are deployed as Flash files, every Flex app “lives” inside the Flash security sandbox, which prevents it from accessing many of the resources of the computer. Also, Flash is a proprietary format that doesn’t run natively but is interpreted by the Flash Player. That extra layer of translation decreases the performance.
  • Classic Flash stuff. Don’t bother to learn Flex if all you need to do is Flash banners and simple animations. For that you will need a timeline, drawing tools and accuracy at pixel-level. Flex is not designed for that.
  • Being extrovert with its neighbours. I hear that even Air makes it quite difficult to launch an external executable from a Flex application.

Now, the “hello world” is mandatory, so here it goes.

This application simply displays a customised greeting (it’s a “hello world” on steroids). We’ll make the GUI inherit from the layer that processes the information, in a “code-behind” manner.

First, the Actionscript class contained in the file info/tripu/blog/flex/SimpleApp.as. This class extends the standard Application class and defines what to do with data:

package info.tripu.blog.flex {
 
    import mx.controls.Alert;
    import mx.core.Application;
 
    public class SimpleApp extends Application {
 
        public function greet (who:String): void {
            Alert.show ('Hello, ' + who + '!');
        }
 
    }
 
}

Second, the MXML application HelloWorld.mxml. It defines the GUI by using an instance of the class SimpleApp and adding a couple of visual controls to it. Notice how the AS class that we created before is now used straight as an XML element:

<?xml version="1.0" encoding="utf-8"?>
 
<tripu:SimpleApp xmlns:tripu="info.tripu.blog.flex.*" xmlns:mx="http://www.adobe.com/2006/mxml">
 
    <mx:TextInput id="user" text="world" />
    <mx:Button label="Greet" click="{greet (user.text)}" />
 
</tripu:SimpleApp>

The result of compiling those two files in a Flex project is this Flash file, HelloWorld.swf (you’ll need Flash Player version 8 or above to see the embedded Flash object):


20 Mar 2008 3 comments so farAdobe Flex, Computers, Work


Casio EX-word XD-SP7500 Japanese-Spanish-English

Today I ordered this little marvel:

  • 27 thesaurus and dictionaries of Japanese, Spanish and English.
  • Quick jump among dictionaries.
  • Hand-written kanji recognition.
  • Encyclopedias with images.
  • Dictionaries of proverbs, computer jargon, business and economics, kanji and katakana.
  • 10K spoken Japanese words (not synthesised but actual human voice).
  • Backlight.
  • SD card slot.
  • USB port.
  • Speaker plus headphone output.

Hopefully it will find its way from Japan to the UK and will be safe with me in a few days.

Isn’t it beautiful?

17 Mar 2008 8 comments so farComputers, Japanese


Dicotómico

¿Oficio y beneficio
o predecible y apacible?
(podría no ser tan terrible, pero
¿merece la pena el sacrificio?)

Entre el diseño individual
            el control de la necesidad
y
asumir los destinos
            participar de las decisiones.

Entre máquinas y personas
objetos y conversaciones
sentidos y razones
entre el hemisferio izquierdo y el derecho
entre hemisferio norte y hemisferio sur.

Si el menú no sirviera opciones
(o si al menos pudiesen contarse)
si las supiese mesurar
o si fuese yo estúpido
sobraban todas estas líneas torcidas
y ya habría optado
medio camino hecho
un empezar, el objetivo
la ruta y su prioridad
como hacen tantos
sin lamentos como el menda
sin indecisión y sin
blog
y el viaje no les sale mal.
¿Por qué, entonces, el ahogo?
            Soy, ahora lo veo luminoso
            probablemente estúpido, al final.

Más la circunstancia es contraria:
me senté, abrí la carta
            tomo rollizo inflado de menús
empecé a leer hace mucho tiempo
revisando ingredientes
me gustan casi todos
(menos los pistachos)
(y la sandía)
y aún sólo voy por la mitad
de la introducción
al primer volumen
de los entrantes…

Porque todo me apetece del menú
se me antoja y me encanta y lo deseo
como al asno de Buridán:

Dibujar con el alfabeto
admirar a los que saben pintar de verdad
páginas de historias verdaderas
en colores sintéticos, o al revés
saber de otros que admiran igual
leer todo de todos ellos
escribir lo que aprenda
más lo que me sepa inventar
jugar con trastos
que son un mundo cada uno
los que se tocan y los que no
todos los juguetes espectaculares
que se pueden diseñar
hacer otros trastos yo mismo
que otros a su vez puedan usar
hacer el amor por amor al arte
o simplemente por gusto
sobre cada pieza de mobiliario
de nueve a seis
y con más de tres
no quiero decir a la vez
(pero todo se puede ver)
comer sin tenedor ni pan
probar lo que me pongan
vivir como un oriental
en el cono sur
de la Europa tropical
tan lejos, es casi volver ya
hablando raro
juntarme con extravagantes
a los que miran mal
hasta que ésos me entiendan
y entonces volver a empezar
ser en paralelo a mis compañeros
verlos crecer aún más que yo
citarme cada año
doquiera que estén
saborear cada charla
estrujar cada ciudad
atrapando cada imagen
que no quiero olvidar
que es cada imagen
sudar más cuando se imponga rendir
mejorar
aprender
absorber todo lo que me hace bien
que es tanto
y escuchando todo de fondo
mientras hago todo lo demás
vibrar con lo que cuentan
también con lo que cantan
crear sonidos que no suenen mal
tachar de las narraciones
que me faltan por ver
que son muchas de las viejas
más las que están por estrenar
saberme lo más
para quien sea todo para mí
a quien no tenga que explicar
el ansia de probar
de sentir
de cambiar
de volver
y de estar
y de ser
o en su defecto
            saber plegarme de una puta vez.

Todo no cabe
eso lo sé.

Me miro en los reflejos
            de los que necesito pero no lo admito
            a los que admiro, que me inspiran
            de los que aprendo
            ¿que me entienden?
hago diferencias e infiero resultados
analizo los porqués de
sus caminos en sus variaciones
toda mi querida parafernalia que no basta
ni arroja resultados
por más que viva
y le dé vueltas
y vuelva a reconsiderar o
corrija la ecuación.

Y si volver es el argumento
más correcto
que es cierto, que más vale
¿volver a qué, exactamente?
Dime cuál es el origen
si alguno hay
y si cruel no es el volver a él
(¿no me toca a mí inventar uno ya?)

Continuará…

17 Mar 2008 One comment so farLife