Category Archives: J

Statistica con J

jredSi può usare J, la mia ultima scoperta?
Ci sono dei casi in cui, mi dicono, è proprio quello che ci vuole. Allora, ci ho provato. Confesso che sono ancora mooolto n00b|niubbo ma ho cominciato a leggere la documentazione (è un mattone!), con scarsi risultati per adesso. Questo post è un primo tentativo di valutazione, anche in funzione di un incontro con un guru di J, R e altri linguaggi orientati alla matematica e statistica. Mi preparo a una ramanzina di quelle mai viste.
Se nel frattempo arrivassero suggerimenti… chissà 😉

Il caso che considero è elementare: calcolare media e deviazione standard (sigma) di una serie di dati.
Si può fare facilmente in millemila modi, ne considero tre, tipici secondo me.

J è fatto apposta e allora proviamolo. Cioè vorrei ma la cosa non è così semplice (sono ancora un pivello, l’ho già dichiarato).
Dalla documentazione che arriva con l’installazione (o da una successiva googlata, non ricordo esattamente) ho messo assieme questo script. Pessimo, sono un pischello, non ho trovato come passare i dati sulla linea di comando. E J mi fa rimpiangere finanche Perl!

#!/home/juhan/bin/j7
mean =: +/ % #
dev =: - mean
stddev =: [: %:@mean *:@dev

dati =: (1 2 3 4 5)
echo 'dati = ' , ": dati
m =: mean dati
echo 'mean = ' , ": m

d =: dev dati
echo 'dev = ' , ": d

stdd =: stddev dati
echo 'std_dev = ' , ": stdd
exit''

std_j

Mi piace poco la shebang, si deve cambiarla cambiando macchina; forse il symlink j7 conviene spostarlo in /bin quando si installa J.

E se –solo per adesso finché scopro come si usa davvero J— lo script fosse eseguito dalla shell, che invoca j7 attraverso una pipe? In questo modo riesco a passare i dati sula linea di comando.
Questo modo di usare la pipe non funziona però con Windows. E anche $* e la shebang e l’opzione -n di echo. Insomma con Windows si dovrebbe operare in modo completamente differente (ho anche un abbozzo ma lo tengo per il futuro).

#!/bin/sh
echo dati = $*
echo -n "   media ="
echo "(+/ % #)" $* | j7
echo -n variance =
echo "(- (+/ % #))" $* | j7
echo -n std dev =
echo "([: %:@(+/ % #) *:@(- (+/ % #)))" $* | j7
echo ""

m_j

Ma non c’è solo J, per fortuna!

Il linguaggio di programmazione ideale per queste cose, secondo me, è Python. O Ruby, o Lua, o Falcon, o quello cui siete abituati.
Con Python è facilissimo e, a differenza del precedente, chiaro:

s = [1, 2, 3, 4, 5]
def average(s): return sum(s) * 1.0 / len(s)
avg = average(s)
print "avg =", avg
variance = map(lambda x: (x -avg)**2, s)
print "variance =", variance
print "average(variance) =", average(variance)
std_dev = average(variance)**0.5
print "std_dev =", std_dev

stddev

OK, l’ho trovato sul Web (mentre cercavo per J). E dentro si trovano sia map() che lambda(). Non che siano necessari ma fa fine, imho. Devo abituarmi a usarle più spesso.

La versione Python (o linguaggio affine, come detto sopra) è la mia versione. Non avrei difficoltà a modificarla, stravolgerla al volo se se ne presentasse l’occasione. Niente panico 😀

OK, in realtà esiste una terza soluzione, l’ho lasciata per ultima ma sarebbe quella utilizzata nella quasi totalità dei casi: la soluzione del mio amico Beppe S, quella che impiega Excel, o un altro foglio di calcolo, io ho usato LibreOffice Calc (ma l’ho verificata con Excel, funziona anche di là).

excel

L’unica difficoltà (sono niubbo) è stato trovare il nome della funzione, STD.DEV.POP().

Per il resto è OK, anche i dati si riescono (loro io sono n00b) a copia-incollare nella relazione, scritta usando Word. E volendo riesco anche a diagrammare all’interno del foglio di calcolo: nessuno ama Gnuplot.

Riguardo J: devo ancora leggere un mucchio di roba ma continuo a domandarmi se ha senso usare verbi di una o due lettere, per niente mnemonici. Allergia alla tastiera?

Panico: adesso pare non funzionino le opzioni per la selezione, copia e stampa dei codici inseriti, chissà se è solo temporaneo 😮 😦

lcm – J (e Python)

La serie su lcm  –minimo comune multiplo– continua, ancora per questa puntata. Poi come tutte le cose belle (a me è piaciuta questa passeggiata in territori nuovi (per me)).
I post precedenti sull’argomento (proposto dall’amica Annarita) li trovate qui, qui e qui.

Oggi una cosa completamente diversa, frutto della googlata per vedere quali linguaggi trattavano l’argomento e come. Subito sono arrivato a una pagina molto interessante e non vi dico la fatica per riuscire a non dirvelo finora!

rosetta

Rosetta Code è davvero da seguire, lcm lo trovate qui: Least common multiple.

Uh! 60 linguaggi, alcuni mai sentiti. Ma tra i tanti (c’è anche awk però sarebbe una quasi ripetizione del post sul Fortran) ce n’è (secondo me) uno speciale: J.

J provides the dyadic verb *. which returns the least common multiple of its left and right arguments.

Vero che ci sarebbero anche altre cose interessanti: CL (i saputi non dicono mai Common Lisp), Factor e Haskell ce l’hanno già pronto. Ma torno a J.

J

Questa è l’occasione buona per installarlo, me ne hanno parlato in passato, ne ho parlato anch’io e oggi è il giorno di ora o mai più.

L’installazione si fa partendo dalla J Home, crea due directories nella home (su Linux, esiste anche la versione Windows). Ci sono tre modalità d’uso: classica, nel browser e con GUI. Io che sono vecchio uso la migliore.

Siccome l’installazione è non standard la prima cosa che conviene fare è un link simbolico (quello che in Nautilus viene chiamato collegamento) all’interprete, nel mio caso ecco il risultato:

link

Allora proviamo…

j0

Funziona! Un paio di dritte per chi, come me, non afferra subito tutto al volo:

  • il prompt di J è 3 spazi, quasi invisibile;
  • exit'' per uscire, non vi dico l’energia spesa per trovarlo (leggere il manuale prima! o almeno un’intro).

Esiste anche la possibilità di fare uno script che invochi l’interprete. Però nella shebang dovete mettere la vostra home scritta per bene, non vale ~ e neanche $HOME.

Ma si può fare anche con la shell, così:

#!/bin/sh
echo "(*./)" $* | j7
exit''

j1

OK.

Si può fare un passo ancora, integrare lo script J entro il nostro linguaggio abituale, per esempio Python. Cerrrto usando la pipe.
Avevo già trattato questo argomento nell’antichità, qui ma avevo usato funzioni che adesso sono deprecate e poi si può fare più brevemente, così:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import subprocess

cmd = ['./lcm.j', '3 4 5 6']

res = subprocess.check_output(cmd)
p = res.find('\n')
num = res[:p]
n = int(num)
print n

j2

L’esempio è minimo perché su Python sappiamo tutto vero? E poi devo andare a leggere il manuale di J, promette che in sei mesi dimentico che esistono i loop 😉 🙂 😀