Un IDE per Python — PyCharm

BlogPostPicture_PyCharm4Solo una segnalazione, pare sia utile fare anche queste cose.
Anche se personalmente preferisco occuparmi di cose che –sembra– interessano solo me; prendi il post di ieri sul Lisp che finora ha accumulato 5 (cinque) visite :evil: OK, non sapete cosa vi perdete.
Dunque, tornando al dunque: c’è chi si lamenta che spesso nel mondo Linux manca un ambiente di sviluppo come si deve, tipo VisualStudio per M$Windows. In parte è vero, in parte solo colpa mia. Per me vanno benissimo Gedit (in effetti la versione 64 bit per Linux qualche bug ce l’ha; quella Windows anche), Geany (sì, c’è anche per Windows) e poco altro. Sono vecchio.
Uh! –e qui anticipo in parte la risposta all’amico itfs– mi sto scoprendo allergico anche a quelle cose troppo grosse, tipo Emacs (perdono RMS, non è come sembra, sappitelo o comunque fattene una ragione).
Quindi PyCharm, per Python. Tutto è nato da questo post, visto su Twitter (l’uccellino azzurro si dismostra sempre più indispensabile!): Announcing General Availability of PyCharm 4. Prima di subito Appena possibile sono andato sul sito, qui: The Most Intelligent Python IDE. Ho provato la versione free, Download PyCharm,  la Community Edition, OK, senza i componenti per il web, c’è per Windows. Fatto qualche piccola prova, sembra OK (in realtà ho solo assistito, su Windoze, certo non è VisualStudio ma vabeeene, dicono).

OK :wink: Adesso mi viene un dubbio: questo post riuscirà a battere il record del precedente?
Ma ho anche la risposta, anzi due: fregacazzi, direbbe Zerocalcare, chissene… dicono da queste parti. Forse :grin:

Lisp – REPL, Espressioni, Parentesi e valori ritornati

cons-cellsREPL –read, eval, print loop– è il cuore dell’approccio interattivo del Lisp (e non solo). Siccome tutti sanno cos’è salto la solita spiegazione, tanto ci volesse trova tutto da dove sto copiando, qui: The REPL.
Dai tutto semplicissimo, passo a Expressions, Parentheses, and Return Values.
Già sappiamo che in Lisp ci sono le S-Expressions che vengono valutate in base al loro primo dato e ritornano il valore dell’espressione stessa. Inoltre c’è la quotatura che inibisce la valutazione. Cose note.

Esercizio:


* ;; definisco un paio di variabili
(defvar *test-list-a* '(a b c))
*TEST-LIST-A*
* (defvar *test-list-b* '(d e f))
*TEST-LIST-B*
* (append *test-list-a* *test-list-b*)
(A B C D E F)
* *test-list-a*
(A B C)
* *test-list-b*
(D E F)
* ;; nconc è distruttiva
* ;; per convenzione le operazioni distruttive iniziano con N
* (nconc *test-list-a* *test-list-b*)
(A B C D E F)
* *test-list-a*
(A B C D E F)
* ;; mentre ...
* *test-list-b*
(D E F)
* 

Le espressioni ritornano un valore. Però una chiamata a funzione ritorna il valore dell’ultima form valutata:

Ecco una tipica funzione anonima, l’ultima form del suo corpo è (+ x x) e quindi passandogli 2 ritorna 4.


* ((lambda (x) (+ x x)) 2)
4

In quest’altra il valore ritornato dalla form (+ x x) viene perso:


* ((lambda (x) (+ x x) (* x x)) 10)
100

Ecco come ritornare sia (+ x x) che (* x x) come le variabili lessicali SUM e PRODUCT; usando values vengono ritornati più valori invece di uno solo:


* ((lambda (x) (let ((sum (+ x x)) (product (* x x))) (values sum product))) 10)
20
100
* (values)

*

Come si vede però values da solo non ritorna niente.

Come già visto una S-Expression può essere sia un atomo che una Cons-Cell. Cons-Cell sono rappresentate dalle liste.
Un sottoinsieme degli Atoms è chiamato self-evaluating objects. Sono quelli che ritornano se stessi. Quotando un’espressione la si rende self-evaluating (come si dice da noi? autovalutanti?).

Ecco qualche esempio:

;; strings---
* "a string"
;; characters---
* #\greek_small_letter_lamda
;; numbers
* 42
* #x2A
;; bit-vectors---
* #*1001

Notare che #x2A è 42; si può verificare con:

* (eq 42 #x2a)
T

Le liste sono collezioni ordinate di S-Expressions racchiuse tra parentesi i cui elementi sono separati da blank (spazi, new-line, tab, quelli insomma). Ecco tre volte la stessa lista:

* '(a b c)
(A B C)
* '(a
b
c)
(A B C)
* (list 'a 'b 'c)
(A B C)
Ecco, finora mi sembra di essere nella Easy Way :grin:

Inoltre ecco una frase da incorniciare:

Lisp code is meant to be simple and elegant; if you find yourself staring into an impenetrable confusion of parenthesis-chaos, your code is too complex for you to manage. Using techniques for decomposition and refactoring also presented in this book, you will learn how to write beautiful and elegant programs as well as the Common Lisp language itself.

Bravo Colin :wink:

Visto nel Web – 158

La settimana degli incubi; pasticciato parecchio ma intanto ecco cosa ho visto nel Web.

camicia
10 Tips to Improve Programming Skill and become better Programmer, Developer
::: Javarevisited

C++ è
::: Twitter

Neutralità
della rete
::: Internazionale

piatti

High Performance Web Sites
::: ACMQ

Nuntio Vobis, gaudium magnum
::: Twitter

modify the EXIF metadata of an image
::: The Ubuntu Incident

10 facts about you

Learn X in Y minutes
ma poi ci vogliono anni per diventare über-geek
::: Learn X in Y minutes

Gli e-book come i videogame: l’Ue boccia l’Iva agevolata
::: la Stampa

Open Microsoft
::: SIAMO GEEK

1912091_10152023974644748_156955047_n

Cheaper, Smaller, Curvier; The All New Raspberry Pi A+
::: Linux Voice

Hacklab X – Anno 1, Numero 6
::: Hacklab Cosenza

Clojure Is the New C
interessante tweet-scussione
::: Twitter

newton

Computer Science paradox
::: Twitter

Facebook, Google and Apple lobby for curb to NSA surveillance
::: the Guardian

Il copyright degli enti pubblici e il principio open by default: webinar per Regione Lombardia
::: Simone Aliprandi

1958218_718871114810367_2028412288_n

Court rules Google can arrange search results any way it wants
::: Engadget

A Blow Against the Empire
In 2004, it looked like Microsoft would own browsing forever. Then came a feisty open-source browser called Firefox. And the web was never the same.
::: Medium

cipria biancofiore

NYC To Replace Most of Its Payphones With Free Gigabit WiFi In 2015
::: Slashdot

Faster Python
::: Mark Litwintschik

Learning Haskell as a Nonprogrammer
::: superginbaby

IMG_2228337280450

Nokia’s N1 Android Tablet Is Actually a Foxconn Tablet
::: Slashdot

Clojure is not for geniuses
::: Adam Bard

The Bash Guide
::: Twitter

sbatterelammimnistratore

Wow, 3 resign from Debian TC
::: Twitter

Facebook releases “Flow”, a statically typed JavaScript variant
::: Lambda the Ultimate

dpkg Developer Resigns from Debian Technical Committee over Systemd
::: Softpedia

1186700_2164536803601559_1304537572_n

Cognitive Computing: The New Frontier in Machine Intelligence
::: IBM Data magazine

Amnesty International wants to help you avoid government surveillance
::: Engadget

Computer Science Innovation and the Open Source Multiplier Effect
::: a16z

1544963_530986790336180_1435862417_n

colorize man pages
fatto, funziona
::: The Ubuntu Incident

Ubuntu abbandonerà la versione a 32 bit
::: oneOpenSource

The Shazam Effect
::: The Atlantic

1609653_618451038228626_1459300136_n

i3 tips ‘n’ tricks
::: Extended Reality ::: adesso anche in versione italiana

the API search engine
::: {API}

Pensate di aver cancellato dei file? I malintenzionati li recuperano, ecco come
::: Andrea Lazzarotto

1017523_891496514228762_4947178482023617693_n

Net neutrality looks doomed in Europe before it even gets started
::: Gigaom

Twitter time machine: the first time these important words appeared on Twitter
::: The Next Web

Cargo: Rust’s community crate host
::: The Rust Programming Language

10431711_813387422032919_314431746679137814_n

The end of Linux
panico?
::: Lusis

The book on metaprogramming
::: Twitter

Autunno, tempo di meeting per le Comunità italiane del Software Libero
::: Dario Cavedon (iced)

lolcatsdotcom3gp6wm7dw3jihq9t

How to reward skilled coders with something other than people management
::: lizTheDeveloper

the command “source” doesn’t exactly work the way you thought
ok, difficile, evitare se possibile
::: The Ubuntu Incident ::: The Ubuntu Incident

The Easiest Raspberry Pi Media Centre, With RasPlex
::: makeuseof

sicilia ETNA eruz

Le contraddizioni italiane sulla net neutrality
::: Luca De Biase

Google presenta Contributor, paghi per non vedere la pubblicità sul web
::: la Repubblica

L’emergenza dei prossimi anni sarà ridimensionare Google
::: Twitter

10407876_594779577295302_6971371916763000775_n

Shuttleworrth ama Go, tutto quello che non è in C è scritto in Go
::: Twitter

Announcing General Availability of PyCharm 4
da provare, sembra bello
::: JetBrains
ubuntisti

Ricevere notifiche su Whatsapp quando finisce uno script:il download di un video su youtube

Sono sempre stato un downloader compulsivo e ora ho scritto uno script che mi avvisa su whatsapp quando un download -o uno script- finisce.

Può essere l’installazione di un programma molto pesante, il download di una iso con wget, o (questa non l’ho ancora fatta) avvisare della temperatura della stanza (se abbinato con un cronjob e un sensore).

Se non avete paura della mia soluzione molto incasinata, ecco come faccio.

Installiamo subito un programma che tramite riga di comando ci consente di scaricare dei video da internet


sudo apt-get install youtube-dl

Poi creiamo una cartella “video” che conterrà i file scaricati

mkdir /home/$USER/video

Per prima cosa dobbiamo  installare da github una libreria che ci consenta l’accesso da programma ai server whatsapp.

Si chiama YOWSUP-CLI,  per installarla e configurarla questo l’url

Io ho seguito il tutorial qui presente

Mi raccomando, vi conviene registrarvi con un numero di telefono dove NON avete Whatsapp.

Se avete genitori o nonni, prendete in prestito il loro telefono, ma non usate il vostro numero con cui siete registrati su whatsapp.

Si può programmare in python, ma non conosco bene questo linguaggio, e promette di inviare anche foto (cosa che non sono riuscito a fare, appunto per il motivo di cui sopra)

Quando trovo su Youtube un video che mi piace e voglio scaricare apro un file di testo “list” e ci copio dentro l’URL.

In effetti questo è un file che contiene degli url separati da un a capo.

Ho scritto poi un programma in C  “youload.c” che legge da questo file “list” e genera in output un file “list.sh” e poi lo esegue.

Non chiedetemi perchè ho dovuto ricorrere a questo stratagemma: sono passati diversi mesi e non me lo ricordo più ;)

Sono ricorso all’aiuto di StackOverflow per leggere dal file “list” e memorizzare nella variabile  “line” ogni riga di quel file, dove riga è sinonimo di URL di un video, come intuite.

Successivamente poi nel programma apro il file “list.sh” che è uno script, e da programma C ci scrivo  i comandi che sono necessari affinchè questo script generato automaticamente scarichi ciò che voglio e mi notifichi dell’eventuale successo.

Alla fine del programma eseguo materialmente lo script generato tramite il comando


system("./list.sh");

Affinchè questo programma funzioni dovete sostituire IL_MIO_NUMERO_DI_WHATSAPP e IL_MIO_USERNAME con il vostro numero telefonico e l’username con cui siete loggati al pc.

 


//questo programma si chiama youload.c

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
void strip(char *s) {
char *p2 = s;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
int main(void)
{
char buf[80];
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
FILE *sh;
sh = fopen("list.sh","w");
fp = fopen("list", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
fprintf(sh,"youtube-dl ");
fprintf(sh,"%s", line);
strip(line);
fprintf(sh,"page=$( wget \"%s",line); // "\b" perchè %s,line aggiunge un ritorno a capo che non mi serve
fprintf(sh,"%c\" -O youtube)\n",0x08);

fprintf(sh,"echo -n \"Finito il download di %c\"\" >> whatsapp\n",0x5c); //hex value per "\"

fprintf(sh,"awk -vRS=\"</title>\" \'/<title>/{gsub(/.*<title>|%cn+/,\"\");print;exit}\' youtube >>whatsapp\n",0x5c);

fprintf(sh,"echo \"%c\" alle ore \" >>whatsapp\n",0x5c);

fprintf(sh,"echo $(date +\"%T\") >>whatsapp\n");

fprintf (sh,"echo \" del \" >>whatsapp\n");

fprintf(sh,"date +\"\%cd/\%cm/\%cy\">>whatsapp\n",0x25,0x25,0x25); //0x25=hex value di %
fprintf(sh,"a=$(cat whatsapp | tr -d \"");
fprintf(sh,"%cn\"",0x5c);
fprintf(sh,")\n");

fprintf(sh,"yowsup-cli --send 39IL_MIO_NUMERO_DI_WHATSAPP \"$a\" --config /home/IL_MIO_USERNAME/yowsup-master/src/yowsup-cli.config\n");
fprintf(sh,"rm whatsapp\n");
fprintf(sh,"rm youtube\n");
}
fprintf(sh,"yowsup-cli --send 39IL_MIO_NUMERO_DI_WHATSAPP \"Per oggi abbiamo finito!!\" --config /home/IL_MIO_USERNAME/yowsup-master/src/yowsup-cli.config\n");
fclose(sh);
fclose(fp);
if (line)
free(line);
system("cd /home/IL_MIO_USERNAME/video");
system("./list.sh");
exit(EXIT_SUCCESS);

}

Creo anche un altro file “whatsapp” che mi aiuta nella costruzione della stringa finale. Per l’utilità leggere più in basso

Non avete capito niente, lo so e anch’io adesso non ricordo l’iter che mi ha portato a questo procedimento, ma se apriamo lo script che viene generato da questo programma “list.sh”, capiamo subito un po’ di più.


//questo file script "list.sh" è stato generato automaticamente da youload.c

youtube-dl https://www.youtube.com/watch?v=URL_DEL_VIDEO
page=$( wget "https://www.youtube.com/watch?v=URL_DEL_VIDEO" -O youtube)
echo -n "Finito il download di \"" >> whatsapp
awk -vRS="</title>" '/<title>/{gsub(/.*<title>|\n+/,"");print;exit}' youtube >>whatsapp
echo "\" alle ore " >>whatsapp
echo $(date +"%T") >>whatsapp
echo " del " >>whatsapp
date +"%d/%m/%y">>whatsapp
a=$(cat whatsapp | tr -d "\n")
yowsup-cli --send 39IL_MIO_NUMERO_DI_WHATSAPP  "$a" --config /home/MIO_USERNAME/yowsup-master/src/yowsup-cli.config

la riga


page=$( wget "https://www.youtube.com/watch?v=URL_DEL_VIDEO" -O youtube)

awk -vRS="</title>" '/<title>/{gsub(/.*<title>|\n+/,"");print;exit}' youtube >>whatsapp

mi serve per risalire al titolo del video su Youtube. Grazie StackOverflow!

vedete la riga


yowsup-cli --send 39IL_MIO_NUMERO_DI_WHATSAPP  "$a" --config /home/MIO_USERNAME/yowsup-master/src/yowsup-cli.config

usiamo il nome del programma senza “./” per eseguirlo. Ciò significa che è diventato un programma di “sistema”, perchè abbiamo copiato tutto il contenuto di yowsup-master/src in /usr/bin.

 

ESEMPIO

ecco il contenuto di “list”

list

ecco il contenuto di “list.sh”

sh

Ed ecco uno screenshot di whatsapp sul telefono

okpwz

NON BIASIMATEMI PER I TITOLI DEI VIDEO: dovevo controllare semplicemente se funzionava, e ho scelto i filmati più brevi.

Che cosa vi sembra?

Commentate numerosi, perchè so di non essere stato chiaro -ho scritto in fretta- !

Grazie dell’attenzione

61LL35

Help! una richiesta disperata — risolto

Il post è stato modificato, quasi interamente riscritto, sperando di non perdere troppi nerd-punti.

nerd

Quasi, nèh!
Ma c’è una cosa Unixosa che non sono riuscito a fare come vorrei. E penso che sia possibile anche se richiede un grado di überosità –evidentemente– superiore al mio. E se qualcuno dice che in effetti il mio grado è basso assay sappia che:

  • ha ragione; ma
  • non ci faccio più ‘mico.

Vengo al dunque. Per capire di cosa si tratta dovreste dare un’occhiata al post precedente, questo: SBCL – una prima scorsa al manuale.
Quello che vorrei fare è questo:

l0

cioè lanciare sbcl con un banner diverso dal suo, troppo lungo. E non vorrei nemmeno eliminarlo completamente, cosa fatta con l’opzione --noinform.

Ecco la sintesi delle prove fatte:

s0Come si vede per l’alias occorre passare la stinga tra virgolette semplici o doppie; si possono quotare con backslash i caratteri speciali come lo spazio nell’ultimo esempio.

2Tutti i caratteri speciali possono essere backslashati. Il comando che voglio aliasare è questo:

s1Notare come la form Lisp richieda le virgolette. Sono quelle che non sono riuscito a passare. Ho fatto diversi tentativi ma niente, il Lisp non gradisce e continua a dare errore (parte il debug integrato).

A questo punto mi sono perso. Cioè ho seguito un’idea bislacca che provo a raccontare a mia discolpa.
Spesso faccio cose su Linux che poi devono finire su Windows dove è una pratica usuale creare script che lì si chiamano batch, quelli con estensione .bat.
E pensando a Windows ho deciso di chiedere aiuto al web, creando uno shell-script in ~/bin e dopo averlo chmodato il risultato è quello illustrato. Lo script poi è semplicissimo:

#!/bin/bash
echo "Buon hack con SBCL"
sbcl --noinform

Avevo sempre in mente Windows per cui la mia richiesta è stata: “Ma non è elegante. O no? Come farebbe un über-nerd? Qualcuno mi aiuta?

Prima di subito (in realtà dopo le qualifiche per il Gran Premio) lui|61ll35 ha twittato la soluzione.

OK, ecco: alias CL=’echo -e “Buon hack con SBCL” && sbcl –noinform’
Semplice vero? Grazie lui! :grin:

Però, ripensamento: è il mio script trasformato in alias, unendo le due righe con l’operatore AND. E il messaggio non viene dal Lisp.

Insomma: non è quello che volevo; funziona ma non è lui.
Ma in fondo non m’interessa più, ho già perso troppo tempo. E poi devo essere meno impulsivo e occuparmi di meno cose (propositi per l’anno nuovo, un po’ in anticipo) :grin:

SBCL – una prima scorsa al manuale

manualeIl manuale di SBCL, 169 pagine, è una macchina del tempo, almeno per me. Sembra davvero uno di quelli anni ’80 (IBM ma non solo), pieno di cose misteriose, minacce, sigle e procedure che ti fanno pensare “non ce la posso fare”. Per di più l’ho iniziato senza avere la possibilità di verificare subito. Poi quando ho cercato le cose erano cambiate (forse, ma sapete che il Lisp è speciale).
Pare che il REPL sia davvero così come mi è apparso, anzi non è nemmeno nelle loro intenzioni di migliorarlo (p.5): SBCL is essentially a compiler-only implementation of Common Lisp. That is, for all but a few special cases, eval creates a lambda expression, calls compile on the lambda expression to create a compiled function, and then calls funcall on the resulting function object.
E poi (p.6): Though SBCL can be used running “bare”, the recommended mode of development is with an editor connected to SBCL, supporting not only basic lisp editing (paren-matching, etc), but providing among other features an integrated debugger, interactive compilation, and automated documentation lookup.
Currently SLIME (Superior Lisp Interaction Mode for Emacs) together with Emacs is recommended for use with SBCL, though other options exist as well.
Non l’ho ancora installato, aspetto di vedere cosa consiglia Colin the Phoeron Lupton. Anche perché c’è di mezzo Emacs, superlativo ma di nuovo una cosa (quasi) nuova.
Non mi è neanche ben chiaro che tipo di eseguibili crei, sempre che si vogliano ceare.
Le opzioni hanno nomi –come dire– non proprio semplici, non Unix like.
In compenso ho scoperto come eliminare il banner iniziale: --noinform. Ho subito creato l’alias cl='sbcl --noinform', funziona:

l0

Trovato la shebang per eseguire codice come script. In realtà la directory indicata nel manuale non è quella corretta ma c’è whereis :grin:
Testato, funziona anche quello:

l1

Giocato un po’ con l’opzione --eval che consente di eseguire un comando al volo, alcune cose sono ok, altre da chiarire leggendo Colin:

l2

Insomma come conclusione il manuale è decisamente ostico (anni ’80) ci sono parecchie cose che si lasciano intravedere, confido in Colin. O qualche altro libro introduttivo, ce ne sono diversi, alcuni elencati anche qui. Inoltre mi sono dimenticato quasi tutto; ultimamente ho usato newLISP che nel suo piccolo è grande. E semplice; e attuale fatto come si usa adesso.

Lisp – per chi è L(λ)THW e sintassi del linguaggio

large_get_sbcl_mugIl capitolo Preface pt. iii – Who Is This Book For? è da leggere attentamente, sono pienamente d’accordo con –beh– tutto.
Io mi considero (moderatamente) un You are already a Lisper, but want to take your code to the next level ma va bene per tutte le altre categorie. Anzi: You don’t have to know anything about programming or computer science to learn Lisp with this book. Però: I’m going to assume that you know that learning any new skill is hard for everyone, and that you need to work hard in order to succeed. Insomma The Phoeron rockz!
Mi sta venendo un dubbio: se continuo a citare (copiancollando) faccio la cosa giusta? Credo di no, leggetevelo voi. Dai!
Anche se, continuando con l’introduzione, non mi trovo tanto d’accordo con il misticismo del Lisp; almeno per ora. Forse quando sarò un grok fatto e finito… (non sapete cos’è il grokking? è il padroneggiare la materia –facciamo che vi leggete la definizione da Urban Dictionary). No, direttamente da Heinlein, nel capitolo successsivo.

OK, credo sia il momento di una panoramica della sintassi. In Lisp tutto è un oggetto e gli oggetti sono rappresentati da S-Expressions.
Le S-Expressions vengono dal Lambda Calculus, ognuna delle quali può essere un Atom o una List. Le liste sono implementate come Cons-Cells e gli atomi sono tutti gli oggetti che non sono un cons (le Cons-Cells prossimamente).
Viene proposto un primo esercizio, ecco il mio compito. Notare che sono stato mooolto coscienzioso: ho riprodotto l’errore di stumpa per lambda :roll:

ll1

Questi sono diversi tipi di atomi. Come si vede gli atomi possono essere parecchie cose: numeri, simboli, caratteri letterali (?), stringhe e liste vuote. Come si vede nil, '() e () restituiscono la stessa cosa: NIL. Questo perché nil è definito come la lista vuota che viene trattato come atomo visto che non richiede consing.
Le stringhe, trattate come atomi sono in realtà sequenze di caratteri; anche le liste sono sequenze. Per capire cosa succede bisogna considerare la gerarchia degli oggetti. In Lisp ogni oggetto discende da t ad eccezione della lista vuota e la sua rappresentazione nil.
Pertanto t e ogni oggetto che da esso discende rappresenta vero (true) mentre nil falso.

Qualcuno degli esempi sopra è quotato: ha un apice davanti. Questo è una scorciatoia di quote dice a Lisp di non valutare l’oggetto quotato. Esempi di espressioni quotate:

ll2

Le liste sono racchiuse tra parentesi. Ogni oggetto annidato entro una lista è un’S-Expression. Tutto quello non quotato è automaticamente valutato. Queste liste si chiamano form, esempio:

ll3

Cose da notare:

  • una form inizia con una funzione, macro o operatore speciale, tipicamente rappresentato da un simbolo;
  • il resto della form sono i parametri passati alla funzione, macro o operatore speciale;
  • si possono avere altre form come parametri, quelle interne vengono valutate per prime e il loro risultato viene usato come parametro al livello successivo della gerarchia.

Questa sintassi è nota come notazione polacca prefissa. Nel primo esempio è chiaro quello che capita: (+ 10 20 (* 30 2)) diventa dapprima (+ 10 20 60) e poi 90. In casi semplici come questo non se ne vede (purtroppo) la grande semplificazione che porta.
Di solito l’espressione nella posizione di operatore (la prima) di una form è un simbolo che rappresenta una funzione. Può però essere anche una funzione anonima, una macro o una special form. Le special form hanno regole loro, c’è un metodo per definirle. Le marco consentono, tra le altre cose, di creare sintassi personalizzate consentendo l’estensione del linguaggio. Ci sono anche le reader macros che consentono di definire form per trattare nuovi tipi di dati.
Abbiamo già usato una macro: l’apice usato al posto di quote.

Con questa sintassi (è tutta qui) si può esprimere qualunque programma immaginabile, usando il paradigma di programmazione che volete (imperativa, procedurale, object-oriented, or funzionale).

Prossimamente… forse… :roll:

La caccia a un bug mimetizzato

bugIeri ho twittato un cinguettio liberatorio, ero riuscito a stanare un bug storico e dovevo festeggiare, o almeno farlo sapere al mondo intero ai miei follower.
Capita di rado (quasi mai) ma ho scatenato la curiosità di un paio di nerd tosti, di quelli come vorrei essere io (me). È tutto qui.

C’è bisogno, credo, di una premessa. Capita che per un’operazione ripetitiva si appronti al volo uno script di poche righe ma che poi questo cresca e si diffonda e venga modificato da diversi utenti e alla fine non ci sia più chi lo conosce nella sua interezza. O chi lo conosceva se n’è andato ormai da un anno e mezzo.
Inoltre u bug per bene si manifesta solo alcune volte –e mai con me. Anzi m’è capitato che me lo segnalassero e non sono riuscito a riprodurlo, fino a ieri.
Ancora: se non ci fosse questa crescita organica e –ahimè!– spontanea lo script sarebbe molto diverso, e anche più controllabile.

Ho provato a farne una versione mooolto semplificata, spero si riesca a capire qual è il problema.

Il compito dello script (in questa versione ultrasemplice) è di visualizzare un file di testo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os

#directory corrente
wd = os.getcwd()

#file da visualizzare
fvis = wd + "/fdv.txt"

#modo normale
f = open(fvis, "r")
txt = f.read()
f.close()
print txt

norm

Banale, vero. E funziona, se il file da visualizzare esiste.

Per le ragioni che dicevo sopra lo script è diverso, demanda a un secondo script (qui sostituito da cat) la visualizzazione del file:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os

#directory corrente
wd = os.getcwd()

#file da visualizzare
fvis = wd + "/fdv.txt"

#modo usato nello script - buggoso
os.system('cat ' + fvis)

bug

Qui si vede subito dov’è il bug, sono poche righe, scritte bene da me, con commenti. Capita che la realtà sia spesso diversa. Per esempio che lo script che si deve lanciare debba essere scelto in funzione di qualche parametro, che non venga lanciato cat (tra l’altro io uso Linux ma queste cose debbono funzionare su Windows) ma un altro script Python o in qualche altro linguaggio. E la colpa veniva data a quest’ultimo. Anche perché io in genere non uso spazi nei nomi di files e directories.

La soluzione è immediata:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os

#directory corrente
wd = os.getcwd()

#file da visualizzare
fvis = wd + "/fdv.txt"

#modo usato nello script - corretto
if fvis.find(" ") >= 0:
	fvis = '"' + fvis + '"'
os.system('cat ' + fvis)

corr

E sì, basta racchiudere il pathname tra virgolette. E non c’è nemmeno bisogno dell’if, si potrebbe farlo sempre.

Banale vero?
Mi accorgo adesso che c’è un errore s/cono/sono/ ma per questo bug rimando a un prossimo post, forse.

Aggiornamento: nella versione originale il bug non c’era, grazie B.

E se… Common Lisp a modo mio – intro

There Ain’t No Such Thing As A Free Lunch… anything free costs twice as much in the long run or turns out worthless.
Robert A. Heinlein, The Moon Is A Harsh Mistress

ATZ! cominciamo bene! Sì perché con questa quotazione inizia la prefazione di Learn Lisp The Hard Way.

LL

Però, aspetta un attimino (cit.), il terzo capoverso recita:

The biggest secret to Lisp is that it is actually the simplest programming language ever created –and that, coupled with its expressiveness and elegance, is why it is favored exclusively by the best programmers in the world.

OK, ci sono. E non sono solo, chi si aggrega?

In realtà è un libro in fase di scrittura, alpha 0.2, di Colin J.E. Lupton, the Phoeron. Ma il gioco è intrigante anche per quello. Io continuo.

thephoeron

Intanto chi è the Phoeron? Beh ha un blog, con tanto di about, qui: (null ‘()) => T.

Ha anche un blog come Phoeron (che non ho capito bene cos’è ma non credo sia una cosa bella) ma abbandonato da tempo. C’è invece su Twitter (followato).

sbclbutton

Si parla di Common Lisp, SBCL in particolare. Per Ubuntu lo trovate nel Softaware Center, altrimenti sul suo sito.

sbcl

Funziona. E sì, cambiato nome alla directory, LLthw è molto più usabile. Prossimamente si parte, davvero.

Rose e Python & ____

Lo so benissimo che dovrei occuparmi di quello che ho promesso (e prossimamente ci sarà anche itfs :grin:) ma intanto una segnalazione.
slUn blog che ho scoperto da poco, di Rose Ames, di cui so molto poco; è attiva su GitHub con diverse cose, tutte toste.

Siccome io sono un evangelista Python devo riproporvi Prime Time, fresco di giornata, su come si può usare seriamente il proprio ‘puter.

Devo pubblicarlo, anche se di mio ho aggiunto solo laa soppressione dell’a-capo. Ecco:

def numbers():
    i = 1
    while True:
        i += 1
        yield i

def make_filter(prime, prev_filter):
    while True:
        candidate = next(prev_filter)
        if candidate % prime != 0:
            yield candidate

def primes():
    pipeline = numbers()
    while True:
        next_prime = next(pipeline)
        pipeline = make_filter(next_prime, pipeline)
        yield next_prime

prime_generator = primes()
for i in range(100):
    print(next(prime_generator), end=" ")

pt

Voi intanto RSSatela, subito.

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 82 follower