<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Programmazione on Melabit</title>
    <link>https://static.233.196.69.159.clients.your-server.de/it/categories/programmazione/</link>
    <description>Recent content in Programmazione on Melabit</description>
    <generator>Hugo</generator>
    <language>it</language>
    <lastBuildDate>Sun, 06 Oct 2024 06:00:00 +0000</lastBuildDate>
    <atom:link href="https://static.233.196.69.159.clients.your-server.de/it/categories/programmazione/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>70 anni di Fortran (più o meno)</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2024/10/06/70-anni-di-fortran-piu-o-meno/</link>
      <pubDate>Sun, 06 Oct 2024 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2024/10/06/70-anni-di-fortran-piu-o-meno/</guid>
      <description>&lt;p&gt;Pochi giorni fa, il &lt;a href=&#34;https://www.edn.com/1st-fortran-program-runs-september-20-1954/&#34;&gt;20 settembre&lt;/a&gt; per essere precisi, il Fortran ha compiuto 70 anni.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; La data scelta per il compleanno è un po&amp;rsquo; anomala, per i software di solito si celebra la data in cui vengono presentati al pubblico,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; mentre per il Fortran è stato scelto il giorno in cui gli sviluppatori dell&amp;rsquo;IBM hanno eseguito il primo programma scritto in questo linguaggio, ben tre anni prima della presentazione ufficiale.&lt;/p&gt;&#xA;&lt;h4 id=&#34;ad-alto-livello&#34;&gt;Ad alto livello&lt;/h4&gt;&#xA;&lt;p&gt;Ed è una decisione pienamente giustificata, poiché il 20 settembre del 1954 accade qualcosa che avrebbe fatto la storia: per la prima volta un computer esegue un programma scritto in un linguaggio ad alto livello, molto più vicino al modo di pensare di un uomo, invece che in un linguaggio comprensibile solo alle macchine come l&amp;rsquo;assembler.&lt;/p&gt;&#xA;&lt;p&gt;Un evento cruciale, che avrebbe reso la programmazione accessibile ad un numero sempre maggiore di persone, aprendo la strada alla diffusione capillare dei computer e innescando una trasformazione radicale della società e della nostra vita quotidiana. Non a caso David Padua&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; &lt;a href=&#34;https://ucla-biostat-257-2020spring.github.io/readings/fortran.pdf&#34;&gt;sostiene che&lt;/a&gt;&lt;/p&gt;&#xA;&lt;!-- &#xA;&gt; it is almost universally agreed that the most important event of the 20th century in compiling -- and in computing -- was the development of the first Fortran compiler between 1954 and 1957. By demonstrating that it is possible to automatically generate quality machine code from high-level descriptions, the IBM team led by John Backus opened the door to the Information Age.&#xA; --&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;è quasi universalmente riconosciuto che l&amp;rsquo;evento più importante del XX secolo nel campo dei compilatori &amp;ndash; e in quello dell&amp;rsquo;informatica [in generale, ndt] &amp;ndash; è stato lo sviluppo del primo compilatore Fortran tra il 1954 e il 1957. Dimostrando che è possibile generare automaticamente codice macchina di qualità a partire da descrizioni ad alto livello, il team IBM guidato da John Backus aprì le porte all&amp;rsquo;era dell&amp;rsquo;informazione.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h4 id=&#34;il-primo-programma&#34;&gt;Il primo programma?&lt;/h4&gt;&#xA;&lt;p&gt;Per quanto abbia cercato non sono riuscito a trovare il codice di questo primo programma in Fortran, ma non dovrebbe essere troppo diverso da questo,&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2024-10-06-70-anni-di-fortran-piu-o-meno/ibm3.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; &lt;em&gt;IBM 704 Fortran Programmer&amp;rsquo;s Reference Manual, 1956.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;che cerca il numero più grande in una lista di numeri fornita dall&amp;rsquo;utente. Il programma è molto semplice e può analizzare non più di 999 numeri ma, quando l&amp;rsquo;unica alternativa era scorrere a mano colonne e colonne di numeri, doveva essere un bel passo in avanti.&lt;/p&gt;&#xA;&lt;p&gt;Da notare la presenza dell&amp;rsquo;istruzione &lt;code&gt;FREQUENCY&lt;/code&gt;, rimossa nelle versioni successive e più efficienti del compilatore, con la quale il programmatore poteva stimare il numero di volte in cui ciascun ciclo &lt;code&gt;DO&lt;/code&gt; o test logico &lt;code&gt;IF&lt;/code&gt; poteva essere eseguito, dando modo al compilatore di &lt;a href=&#34;https://ucla-biostat-257-2020spring.github.io/readings/fortran.pdf&#34;&gt;ottimizzare il codice macchina generato&lt;/a&gt;. L&amp;rsquo;ottimizzazione  si basava sul nuovo (per l&amp;rsquo;epoca) metodo Monte Carlo, che non è per niente difficile da padroneggiare, ma che deve essere piuttosto difficile da programmare in un linguaggio a basso livello come l&amp;rsquo;assembler. Tanto di cappello per gli sviluppatori del primo Fortran!&lt;/p&gt;&#xA;&lt;h4 id=&#34;ottimizzare-ottimizzare-ottimizzare&#34;&gt;Ottimizzare ottimizzare ottimizzare&lt;/h4&gt;&#xA;&lt;p&gt;La questione dell&amp;rsquo;ottimizzazione del codice generato dal compilatore era essenziale per il successo del nuovo compilatore Fortran. I computer di allora erano estremamente lenti e costosi, e i programmi dovevano essere molto efficienti per riuscire ad eseguire le operazioni richieste senza inutili sprechi di risorse. Il team IBM &lt;a href=&#34;https://ucla-biostat-257-2020spring.github.io/readings/fortran.pdf&#34;&gt;era consapevole&lt;/a&gt; che&lt;/p&gt;&#xA;&lt;!-- &#xA;&gt; if Fortran, during its first months, were to translate any reasonable scientific source program into an object program only half as fast as its hand-coded counterpart, the acceptance of our system would be in serious danger.&#xA; --&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;se il Fortran, nei suoi primi mesi di vita, fosse in grado di tradurre qualsiasi programma sorgente scientifico ragionevole in un programma oggetto con una velocità pari alla metà di quella della sua controparte codificata a mano, l&amp;rsquo;accettazione del nostro sistema sarebbe in serio pericolo.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;E ci sono riusciti. Un programma scritto in Fortran e tradotto in codice macchina attraverso il primo compilatore risultava effettivamente più lento di uno equivalente scritto in assembler, ma molto meno di quanto avessero temuto inizialmente gli sviluppatori.&lt;/p&gt;&#xA;&lt;p&gt;Il grande vantaggio di poter programmare utilizzando un linguaggio ad alto livello, con una sintassi molto vicina all&amp;rsquo;inglese, compensava ampiamente questa perdita di prestazioni. Non a caso, in pochi anni l&amp;rsquo;uso dei linguaggi ad alto livello si diffuse così tanto da mandare l&amp;rsquo;assembler nel dimenticatoio.&lt;/p&gt;&#xA;&lt;h4 id=&#34;notarelle-finali&#34;&gt;Notarelle finali&lt;/h4&gt;&#xA;&lt;p&gt;Il &lt;a href=&#34;http://pages.swcp.com/~walt/ibm.html&#34;&gt;manuale&lt;/a&gt; della prima versione del Fortran era davvero smilzo, appena 54 pagine. Niente a che vedere con i giganteschi tomi odierni, che riempiono 4-500 pagine per insegnare i rudimenti di un linguaggio di programmazione o di uno strumento software.&lt;/p&gt;&#xA;&lt;p&gt;Negli anni &amp;lsquo;80 il Fortran era così popolare in ambito scientifico che poteva essere usato non solo sui grossi mainframe o sulle workstation e i minicomputer tanto diffusi in ambito universitario, ma perfino sui microcomputer economici come il &lt;a href=&#34;https://www.lyonlabs.org/commodore/onrequest/Nevada_FORTRAN_for_the_Commodore_64.pdf&#34;&gt;Commodore 64&lt;/a&gt; e lo &lt;a href=&#34;https://crashonline.org.uk/45/tips.htm&#34;&gt;Spectrum 48K&lt;/a&gt;, oppure (c&amp;rsquo;è bisogno di dirlo?) sul più potente &lt;a href=&#34;https://www.computinghistory.org.uk/det/1702/Apple-II-Apple-Fortran-Language-Reference-Manual/&#34;&gt;Apple II&lt;/a&gt;. Certo, su queste macchinette non si poteva pensare di far girare una simulazione meteorologica o di generare un frattale in tempo reale, ma per imparare nella comodità di casa propria potevano essere più che sufficienti.&lt;/p&gt;&#xA;&lt;p&gt;È curioso che i tre principali linguaggi di programmazione sviluppati negli anni &amp;lsquo;50, Fortran (1954), LISP (1958) e COBOL (1959) siano ancora in uso oggi, dividendosi in modo netto i campi di applicazione: il Fortran per il calcolo scientifico ed ingegneristico, il COBOL in campo finanziario e bancario. E il LISP? Beh, il LISP sta ben nascosto in tante cose odierne, fra cui &lt;a href=&#34;https://www.gnu.org/software/emacs/&#34;&gt;emacs&lt;/a&gt; e &lt;a href=&#34;https://julialang.org/&#34;&gt;Julia&lt;/a&gt;, e comunque rimane sempre il più affascinante dei tre.&lt;/p&gt;&#xA;&lt;h4 id=&#34;bibliografia&#34;&gt;Bibliografia&lt;/h4&gt;&#xA;&lt;p&gt;Qualche link per chi volesse approfondire:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Il sito di riferimento del linguaggio Fortran, &lt;a href=&#34;https://fortran-lang.org/&#34;&gt;fortran-lang.org&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.ibiblio.org/pub/languages/fortran/ch1-1.html&#34;&gt;A Brief History of FORTRAN/Fortran&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;David Padua, &lt;a href=&#34;https://ucla-biostat-257-2020spring.github.io/readings/fortran.pdf&#34;&gt;The Fortran I Compiler&lt;/a&gt;, Computing in Science &amp;amp; Engineering, 2000.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Lee Phillips, &lt;a href=&#34;https://arstechnica.com/science/2014/05/scientific-computings-future-can-any-coding-language-top-a-1950s-behemoth/&#34;&gt;Scientific computing’s future: Can any coding language top a 1950s behemoth?&lt;/a&gt;, Ars Technica, 2014.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Rud Merriam, &lt;a href=&#34;https://hackaday.com/2015/10/26/this-is-not-your-fathers-fortran/&#34;&gt;This Is Not Your Father’s FORTRAN&lt;/a&gt;, Hackaday, 2015.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Liam Tung, &lt;a href=&#34;https://www.zdnet.com/article/this-old-programming-language-is-suddenly-hot-again-but-its-future-is-still-far-from-certain/&#34;&gt;This old programming language is suddenly hot again. But its future is still far from certain&lt;/a&gt;, ZDNET, 2021.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Lo so, ormai non sono più tanto &lt;em&gt;pochi&lt;/em&gt;, ma negli ultimi tempi sono stato assorbito dal trasloco imprevisto del nostro istituto a causa di urgenti lavori di ristrutturazione.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Anche in modo informale, come è successo per Linux, presentato per la prima volta su un &lt;a href=&#34;https://en.wikipedia.org/wiki/History_of_Linux&#34;&gt;newsgroup&lt;/a&gt; dedicato ad un sistema operativo ormai dimenticato.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;David Padua è professore emerito presso il Dipartimento di Informatica dell&amp;rsquo;università dell&amp;rsquo;Illinois a Urbana-Champaign.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Dieci anni!</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2023/12/18/dieci-anni/</link>
      <pubDate>Mon, 18 Dec 2023 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2023/12/18/dieci-anni/</guid>
      <description>&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years.jpg&#34; alt=&#34;&#34;&gt;&lt;p&gt;Dieci anni fa nasceva MelaBit, questo piccolo blog dedicato al mondo Apple, della programmazione e della scienza con un pizzico di nostalgia per il retrocomputing. Sembra ieri quando pubblicai il mio &lt;a href=&#34;https://melabit.com/it/2013/12/18/melabit-il-blog/&#34;&gt;primo articolo&lt;/a&gt;, e invece eccoci qui, nel 2023, a festeggiare il primo decennio di vita di questo spazio online.&lt;/p&gt;&#xA;&lt;p&gt;In tutti questi anni MelaBit è cresciuto insieme a me e a tutti voi lettori, che mi avete sostenuto con i vostri commenti, le condivisioni e il tempo che dedicate a leggere i miei articoli.&lt;/p&gt;&#xA;&lt;p&gt;In questi dieci anni ho avuto il piacere di raccontare le novità di Apple e dei sistemi operativi, scoprire insieme a voi linguaggi di programmazione e software utili e condividerete riflessioni sulle innovazioni tecnologiche. Ho potuto viaggiare nel tempo parlando di mitici computer del passato ed esplorare alcuni affascinanti ambiti della scienza.&lt;/p&gt;&#xA;&lt;p&gt;Voglio ringraziare ognuno di voi per aver reso MelaBit quello che è oggi. Grazie ai miei primi lettori, a chi è arrivato negli anni e a chi ci seguirà in futuro. Il viaggio continua, tutti insieme!&lt;/p&gt;&#xA;&lt;hr style = &#34;border: none; &#xA;            border-top: 3px double #333; &#xA;            color: #333; &#xA;            overflow: visible; &#xA;            height: 5px; &#xA;            width: 50%; &#xA;            margin-left: auto; &#xA;            margin-right: auto;&#34;&#xA;&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;Post Scriptum&lt;/em&gt;. Per l&amp;rsquo;immagine di copertina ho lasciato fare all&amp;rsquo;&lt;a href=&#34;https://designer.microsoft.com/image-creator&#34;&gt;IA di Microsoft&lt;/a&gt; (eh già!). Secondo me ha fatto un buon lavoro, ma alcune alternative erano altrettanto valide, come si può vedere qui sotto. Peccato solo per gli strafalcioni nell&amp;rsquo;ultima immagine, sarà pure artificiale ma un ripassino di grammatica questa intelligenza dovrà pur farlo!&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years-alt1.jpg&#34; alt=&#34;&#34;&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years-alt2.jpg&#34; alt=&#34;&#34;&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years-alt3.jpg&#34; alt=&#34;&#34;&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years-alt4.jpg&#34; alt=&#34;&#34;&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2023-12-18-dieci-anni/melabit-ten-years-alt5.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Swift contro Python, ovvero mele contro pere</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2022/10/03/swift-contro-python-ovvero-mele-contro-pere/</link>
      <pubDate>Mon, 03 Oct 2022 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2022/10/03/swift-contro-python-ovvero-mele-contro-pere/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2022-10-03-swift-contro-python-ovvero-mele-contro-pere/martina-leuderalbert-i-GgDz7KQz4-unsplash.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; &lt;em&gt;Fonte: &lt;a href=&#34;https://unsplash.com/@tinaleuderalbert&#34;&gt;Martina Leuderalbert&lt;/a&gt; su &lt;a href=&#34;https://unsplash.com&#34;&gt;Unsplash&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Alle elementari la maestra mi aveva insegnato a non sommare le mele con le pere, cioè a non mettere insieme (o paragonare) cose e fatti molto diversi fra loro. Non ha quindi senso sommare 3 litri di acqua con 5 chilogrammi di farina o chiedersi se 40 metri sono più o meglio di 20 secondi.&lt;/p&gt;&#xA;&lt;p&gt;Quello che diceva la mia maestra lo dicono, sono sicuro, le maestre di tutto il mondo, ma c&amp;rsquo;è sempre qualcuno assente a queste lezioni.&lt;/p&gt;&#xA;&lt;h4 id=&#34;il-golia-della-programmazione-moderna&#34;&gt;Il Golia della programmazione moderna&lt;/h4&gt;&#xA;&lt;p&gt;Uno di questi è stato di sicuro Ari Joury che, nonostante il suo dottorato in fisica delle particelle, non si è fatto scrupoli a pubblicare su Medium questo &lt;a href=&#34;https://medium.com/geekculture/swift-was-poised-to-replace-python-then-it-tanked-3e6c11740ba6&#34;&gt;Swift was poised to replace Python. Then it tanked&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Cosa dice l’articolo? Che nel mondo del machine learning i linguaggi di programmazione più usati sono Matlab, R, Julia e soprattutto Python. Quest’ultimo, nato originariamente per sviluppare dei piccoli &lt;em&gt;script&lt;/em&gt; senza troppe pretese, è diventato oggi un vero &lt;em&gt;&amp;ldquo;Golia della programmazione moderna”&lt;/em&gt;, tanto da essere usato estensivamente da aziende come Dropbox, Instagram e Pinterest per i loro servizi online.&lt;/p&gt;&#xA;&lt;p&gt;Grazie alla disponibilità di librerie come TensorFlow o PyTorch (nonché, aggiungo io, di librerie di base come Pandas o NumPy), Python è diventato anche il linguaggio di elezione di chi si occupa di machine learning e di analisi dei dati.&lt;/p&gt;&#xA;&lt;p&gt;La crescita di Python sembra bloccata da un paio di anni, ma la sua enorme diffusione lo farà rimanere comunque un attore centrale anche nel prossimo futuro.&lt;/p&gt;&#xA;&lt;h4 id=&#34;entra-in-scena-swift&#34;&gt;Entra in scena Swift&lt;/h4&gt;&#xA;&lt;p&gt;Fin qui tutto vero e condivisibile. Magari si potrebbe eccepire qualcosina sull&amp;rsquo;importanza di R nell&amp;rsquo;ambito dell&amp;rsquo;analisi dei dati, ma non voglio essere puntiglioso.&lt;/p&gt;&#xA;&lt;p&gt;Il guaio è che se uno si limita a scrivere queste cose non se lo fila nessuno, chi vorrà mai leggere l&amp;rsquo;ennesimo articolo generico sulle virtù di Python per il machine learning (e non) o su &lt;a href=&#34;https://towardsdatascience.com/why-python-is-not-the-programming-language-of-the-future-30ddc5339b66&#34;&gt;quale linguaggio&lt;/a&gt; è destinato a soppiantarlo?&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Ci vuole un colpo d&amp;rsquo;ala.&lt;/p&gt;&#xA;&lt;p&gt;Per fortuna c&amp;rsquo;è sempre Apple che, come il nero, va bene su tutto e, soprattutto, garantisce sempre un bel po&amp;rsquo; di click. E allora perché non mettere in mezzo Swift?&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.apple.com/swift&#34;&gt;Swift&lt;/a&gt; è un linguaggio di programmazione sviluppato da Apple con l&amp;rsquo;obiettivo specifico di sostituire &lt;a href=&#34;https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html&#34;&gt;Objective-C&lt;/a&gt; come linguaggio di elezione per lo sviluppo delle applicazioni per iOS e per macOS. Swift è facile da imparare e la sua sintassi leggibile ricalca quella di Python, è vero, così come quella di Julia e di tanti altri linguaggi di programmazione moderni.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Swift però non ha mai preteso di essere, come &lt;a href=&#34;https://medium.com/geekculture/swift-was-poised-to-replace-python-then-it-tanked-3e6c11740ba6&#34;&gt;sostiene il nostro Ari&lt;/a&gt;, il nuovo &lt;em&gt;&amp;ldquo;Re della Programmazione&amp;rdquo;&lt;/em&gt;. Ad Apple non interessa posizionare Swift come uno strumento di programmazione &lt;em&gt;general purpose&lt;/em&gt;, le interessa solo che venga usato per programmare le applicazioni per i suoi sistemi operativi. Del resto, il fatto che manchi di una versione per Windows taglia fuori una fetta così importante di potenziali utenti da rendere impossibile a priori una pretesa tanto assurda.&lt;/p&gt;&#xA;&lt;p&gt;A maggior ragione Swift non ha mai preteso di essere il nuovo strumento principe per il machine learning, come il buon Ari sotto sotto ci vuole far intendere. È vero che Google ha provato a &lt;a href=&#34;https://tensorflow.org/swift&#34;&gt;supportare Swift&lt;/a&gt; all&amp;rsquo;interno di TensorFlow (di cui Google è il principale sviluppatore), ma questo esperimento, come succede con tanti altri prodotti dell&amp;rsquo;azienda di Mountain View, è stato interrotto nel 2021. È ragionevole pensare, infatti, che chi sviluppa in Swift preferisce usare gli &lt;a href=&#34;https://developer.apple.com/machine-learning&#34;&gt;strumenti per il machine learning integrati&lt;/a&gt; in macOS/iOS piuttosto che prodotti di terze parti.&lt;/p&gt;&#xA;&lt;h4 id=&#34;io-sono-più-popolare-di-te&#34;&gt;Io sono più popolare di te&lt;/h4&gt;&#xA;&lt;p&gt;Ma la cosa più sconcertante è pretendere di confrontare la popolarità (o meno) dei linguaggi di programmazione utilizzando una metrica fasulla come la percentuale di domande poste ogni mese su StackOverflow relativamente ad uno o ad un altro linguaggio. In base a questa percentuale, la &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=python%2Cswift&#34;&gt;popolarità di Python&lt;/a&gt; è cresciuta costantemente fino alla fine del 2020, per poi stabilizzarsi al 16% del totale delle domande su StackOverflow, mentre &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=python%2Cswift&#34;&gt;quella di Swift&lt;/a&gt; dopo aver raggiunto un massimo del 3% è in declino e ora si aggira nei dintorni dell&#39;1.5%.&lt;/p&gt;&#xA;&lt;p&gt;Perché è una metrica fasulla? Perché finché siamo sui grandi numeri e confrontiamo la &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=python%2Cjavascript&#34;&gt;popolarità di Python con quella di JavaScript&lt;/a&gt; può anche avere senso basarsi sul numero di domande poste su StackOverflow per valutarne la diffusione.&lt;/p&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2022-10-03-swift-contro-python-ovvero-mele-contro-pere/stack-overflow-python-javascript.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Ma se buttiamo nel calderone anche la terna &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=python%2Cjavascript%2Cjava%2Chtml%2Ccss%2Cphp&#34;&gt;HTML, CSS e PHP&lt;/a&gt;, che sono ancora oggi tre strumenti fondamentali per chi fa sviluppo web, troviamo che questi ultimi sono in costante declino, senza però che la decadenza (su StackOverflow) di PHP venga compensata da un incremento corrispondente nell&amp;rsquo;interesse verso JavaScript.&lt;/p&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2022-10-03-swift-contro-python-ovvero-mele-contro-pere/stack-overflow-python-javascript-html-css-php.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Anche &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=wordpress&#34;&gt;Wordpress&lt;/a&gt;, che piaccia o non piaccia sta dietro il 40% dei siti web, secondo la metrica di StackOverflow sarebbe in calo. Idem per &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=mysql&#34;&gt;MySQL&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;E allora la spiegazione può essere un&amp;rsquo;altra: più che la diffusione, le domande su StackOverflow ci fanno vedere la complessità del linguaggio e la qualità della sua documentazione: HTML, CSS e PHP (o Wordpress e MySQL) sono prodotti ben assestati, per loro esistono ottime guide sul web che ne spiegano diffusamente i segreti. Di conseguenza non è necessario cercare risposte più o meno occasionali su StackOverflow, e comunque quelle che ci sono già bastano ed avanzano.&lt;/p&gt;&#xA;&lt;p&gt;Python e JavaScript, al contrario, hanno una sintassi di base piuttosto semplice ma per essere usati al meglio hanno bisogno di un gran numero di librerie aggiuntive, che sono spesso più complesse del linguaggio base e che vengono aggiornate ed espanse di continuo. La documentazione relativa non tiene sempre il passo dello sviluppo, per cui il modo migliore per imparare ad usare al meglio le centinaia e centinaia di API disponibili è quello di rivolgersi a qualche esperto su StackOverflow, spingendo così in alto la &lt;em&gt;popolarità&lt;/em&gt; dei due linguaggi.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Secondo la logica basata sul numero di domande su StackOverflow anche &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=c%2Cc%2B%2B&#34;&gt;C e C++&lt;/a&gt;, i linguaggi usati per la programmazione di sistema (e non) su Linux e Windows, sarebbero in declino, e lo stesso succede a &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=algorithm%2Carchitecture%2Cclass%2Cdatabase&#34;&gt;concetti di base&lt;/a&gt; come &lt;em&gt;algoritmo&lt;/em&gt;, &lt;em&gt;architettura&lt;/em&gt;, &lt;em&gt;classe&lt;/em&gt; o &lt;em&gt;database&lt;/em&gt;. Ma  sono in declino perché c&amp;rsquo;è davvero poco interesse o solo perché anche per loro c&amp;rsquo;è abbondanza di documentazione di ottimo livello, senza doversi ridurre a porre sempre delle nuove domande su StackOverflow?&lt;/p&gt;&#xA;&lt;p style=&#34;border-style:solid; border-color:lightblue; background-color:lightyellow; padding:1em;&#34;&gt;Nel mio piccolo lo faccio anch&#39;io: quando programmo in R uso pochissimo StackOverflow, perché posso usare l&#39;ottimo help in linea di RStudio e perché la documentazione che accompagna le librerie aggiuntive di R è centralizzata sul [CRAN](https://cran.r-project.org/) (_The Comprehensive R Archive Network_) ed è di altissima qualità. E quando tutto questo non basta, posso trovare decine di siti e di blog che spiegano benissimo gli aspetti più ostici del linguaggio. Quando passo a Python (un linguaggio che, sia chiaro, mi piace parecchio), StackOverflow diventa quasi una necessità, perché la frammentazione e la mancanza di sistema di gestione centralizzata delle librerie di Python rendono molto più complicato trovare documentazione aggiornata di qualità.&#xA;&lt;/p&gt;&#xA;&lt;h4 id=&#34;decaduto-o-semplice&#34;&gt;Decaduto o semplice?&lt;/h4&gt;&#xA;&lt;p&gt;Swift è un linguaggio semplice con una ottima &lt;a href=&#34;https://www.swift.org/documentation/&#34;&gt;documentazione ufficiale&lt;/a&gt;, un eccellente strumento di apprendimento del linguaggio (e non solo) come &lt;a href=&#34;https://www.apple.com/it/swift/playgrounds/&#34;&gt;Swift Playgrounds&lt;/a&gt; e un numero relativemente ridotto di &lt;a href=&#34;https://codersera.com/blog/open-source-swift-libraries/&#34;&gt;librerie aggiuntive&lt;/a&gt;, c&amp;rsquo;è davvero bisogno di passare un sacco di tempo su StackOverflow per usarlo al meglio?&lt;/p&gt;&#xA;&lt;p&gt;Guardando il grafico relativo al numero di domande relative a Swift ci si accorge che i picchi di interesse corrispondono alle date di presentazione della versione 1.0 (giugno 2014) e al rilascio delle versioni 2.0 (settembre 2015), 3.0  (settembre 2016) e 5.0 (marzo 2019) e, come è naturale, dopo ogni presentazione l&amp;rsquo;interesse tende a decadere, proprio perché per usare il linguaggio c&amp;rsquo;è davvero poco da chiedere su StackOverflow.&lt;/p&gt;&#xA;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2022-10-03-swift-contro-python-ovvero-mele-contro-pere/stack-overflow-swift.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;A supporto di questa tesi c&amp;rsquo;è il risultato di &lt;a href=&#34;https://data.stackexchange.com/stackoverflow/query/edit/1649394&#34;&gt;questa semplice query SQL&lt;/a&gt;, con la quale ho provato a calcolare il numero di domande poste su StackOverflow ogni anno. Di SQL ne so pochissimo per cui dovete prendere i risultati con le pinze, ma sembra che il numero di domande su StackOverflow sia in progressiva diminuzione, da un massimo di 2.2 milioni di domande nel 2016 a 1.6 milioni nel 2021.&lt;/p&gt;&#xA;&lt;p&gt;Una volta raggiunta una base di conoscenza sufficientemente ampia non ha molto senso porre sempre delle nuove domande (che su StackOverflow sono fortemente scoraggiate) ma ci si può limitare ad utilizzare il materiale già esistente. Questo almeno per le tecnologie più stabili, come possono essere HTML, CCS, PHP, Wordpress, MySQL&amp;hellip; oppure Swift. Quando invece abbiamo a che fare con strumenti in rapidissima evoluzione, come Python o JavaScript, StackOverflow diventa davvero il modo migliore per imparare.&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;C&amp;rsquo;è bisogno di dilungarsi ancora? Non credo, dico solo che basarsi su ipotesi fantasiose o metriche poco affidabili per ipotizzare &lt;a href=&#34;https://medium.com/geekculture/swift-was-poised-to-replace-python-then-it-tanked-3e6c11740ba6&#34;&gt;scenari catastrofici&lt;/a&gt; per Swift (o, al contrario, &lt;a href=&#34;https://towardsdatascience.com/bye-bye-python-hello-julia-9230bff0df62&#34;&gt;scenari entusiasmanti&lt;/a&gt; per Julia&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;) mi pare francamente &lt;a href=&#34;https://xkcd.com/558/&#34;&gt;insensato&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2022-10-03-swift-contro-python-ovvero-mele-contro-pere/dt140323.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; &lt;em&gt;Fonte: &lt;a href=&#34;https://dilbert.com/strip/2014-03-23&#34;&gt;Dilbert&lt;/a&gt; di Scott Adams&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Capo: Non si possono confrontare mele e arance.&lt;/p&gt;&#xA;&lt;p&gt;Dilbert: È chiaramente sbagliato, perché li hai appena confrontati e dichiarati diversi.&lt;/p&gt;&#xA;&lt;p&gt;Wally: Mele e arance sono entrambi alimenti che crescono sugli alberi. Sarebbe assolutamente valido confrontarli dal punto di vista nutrizionale.&lt;/p&gt;&#xA;&lt;p&gt;Dilbert: Ho notato che molte delle cose che escono dalla tua bocca non hanno senso.&lt;/p&gt;&#xA;&lt;p&gt;Capo: Parli come mia moglie.&lt;/p&gt;&#xA;&lt;p&gt;Wally: Non puoi paragonare tua moglie al tuo subordinato. Sono mele e arance.&lt;/p&gt;&#xA;&lt;p&gt;Capo: Cosa sta succedendo qui?&lt;/p&gt;&#xA;&lt;p&gt;Wally: Non lo so, ma non lo paragonerei a lavoro.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Ari sembra avere le idee un po&amp;rsquo; confuse sul futuro di Python, dato che su Medium ha anche pubblicato &lt;a href=&#34;https://towardsdatascience.com/why-python-is-not-the-programming-language-of-the-future-30ddc5339b66&#34;&gt;Why Python is not the programming language of the future&lt;/a&gt;, oppure &lt;a href=&#34;https://towardsdatascience.com/bye-bye-python-hello-julia-9230bff0df62&#34;&gt;Bye-bye Python. Hello Julia!&lt;/a&gt; e perfino &lt;a href=&#34;https://levelup.gitconnected.com/why-tensorflow-for-python-is-dying-a-slow-death-ba4dafcb37e6&#34;&gt;Why TensorFlow for Python is dying a slow death&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;E non è un caso, perché alla base di tutti questi linguaggi c&amp;rsquo;è sempre il buon vecchio &lt;a href=&#34;https://time.com/69316/basic/&#34;&gt;BASIC&lt;/a&gt;, il primo linguaggio di programmazione davvero per tutti, che è stato il linguaggio di base dei computer personali degli anni &amp;lsquo;80 su cui si sono fatti le ossa tutti i grandi nomi dell&amp;rsquo;informatica di quegli anni.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Le sole domande sulla libreria &lt;code&gt;pandas&lt;/code&gt; di Python (una libreria fondamentale per chi usa Python per l&amp;rsquo;analisi dei dati) &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=pandas&#34;&gt;assommano al 3%&lt;/a&gt; del totale, le principali librerie per il machine learning (TensorFlow, Keras, PyTorch, scikit-learn, OpenCV, NLTK) fanno &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=tensorflow%2Ckeras%2Cpytorch%2Cscikit-learn%2Copencv%2Cnltk&#34;&gt;un altro 2%&lt;/a&gt;, mentre quelle su &lt;code&gt;Django&lt;/code&gt; e &lt;code&gt;Flask&lt;/code&gt; (le principali librerie Python per lo sviluppo di applicazioni per il web) sono quasi &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=django%2Cflask&#34;&gt;al 2.5%&lt;/a&gt; del totale generale. Chiaramente queste domande vengono anche conteggiate come domande relative a Python.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;Perché sì, &lt;a href=&#34;https://insights.stackoverflow.com/trends?tags=julia&#34;&gt;l&amp;rsquo;interesse per Julia&lt;/a&gt; sembra essere in aumento su StackOverflow, ma parliamo di non più dello 0.16% (1/10 dei valori di Swift) e anche in questo caso i picchi corrispondono al rilascio delle varie versioni del linguaggio.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>JuliaCon 2021</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2021/07/23/juliacon-2021/</link>
      <pubDate>Fri, 23 Jul 2021 12:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2021/07/23/juliacon-2021/</guid>
      <description>&lt;p&gt;Julia è l&amp;rsquo;ultimo arrivato fra i linguaggi di programmazione scientifici, che ambisce a combinare la velocità del Fortran con la semplicità sintattica e l&amp;rsquo;interattività di Python.&lt;/p&gt;&#xA;&lt;p&gt;Un&amp;rsquo;altra particolarità molto interessante di Julia è il supporto nativo agli &lt;em&gt;ambienti&lt;/em&gt;: ciascun progetto scritto in Julia può avere un suo ambiente specifico, contenente il compilatore,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; le librerie e gli eventuali package aggiuntivi necessari, nelle versioni che garantiscono il perfetto funzionamento del progetto. La gestione degli ambienti è ancora oggi una delle principali debolezze di Python, averli integrati direttamente nel linguaggio di programmazione dovrebbe rendere più semplice la scrittura di &lt;a href=&#34;https://rescience.github.io/&#34;&gt;codice &lt;em&gt;riproducibile&lt;/em&gt;&lt;/a&gt;, il Santo Graal del software scientifico odierno.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://static.233.196.69.159.clients.your-server.de/img/2021-07-23-juliacon-2021/world_2800.png&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; &lt;em&gt;Fonte: &lt;a href=&#34;https://juliacon.org/2021&#34;&gt;JuliaCon 2021&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Perché parlo di Julia? Perché la settimana prossima inizia il &lt;a href=&#34;https://juliacon.org/2021&#34;&gt;JuliaCon 2021&lt;/a&gt;, un&amp;rsquo;ottima occasione per iniziare a conoscere questo interessante linguaggio di programmazione. La &lt;a href=&#34;https://juliacon.org/2021/tickets/&#34;&gt;registrazione&lt;/a&gt; è gratuita per cui non ci sono rischi, nemmeno per il portafoglio.&lt;/p&gt;&#xA;&lt;p&gt;In attesa dell&amp;rsquo;inizio della Conferenza, si stanno tenendo dei &lt;a href=&#34;https://juliacon.org/2021/workshops/&#34;&gt;workshop preliminari&lt;/a&gt; molto interessanti che possono già essere visti su YouTube (o potranno essere visti in diretta nei prossimi giorni), senza nemmeno la necessità di installare l&amp;rsquo;ennesimo sistema di videoconferenza. Per quanto mi riguarda, finito il post mi guarderò &lt;a href=&#34;https://www.youtube.com/watch?v=IlPoU5Yr2QI&#34;&gt;Statistics with Julia from the ground up&lt;/a&gt;, mentre lunedì mi aspetta &lt;a href=&#34;https://www.youtube.com/watch?v=W_ExvidyESg&#34;&gt;Introduction to Bayesian Data Analysis&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Per chi preferisce leggere, consiglio questo articolo generale del sempre bravissimo Jeffrey Perkel, &lt;a href=&#34;https://www.nature.com/articles/d41586-019-02310-3&#34;&gt;Julia: come for the syntax, stay for the speed&lt;/a&gt;, e questo post su Towards Data Science, &lt;a href=&#34;https://towardsdatascience.com/bye-bye-python-hello-julia-9230bff0df62&#34;&gt;Bye-bye Python. Hello Julia!&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Buona visione (o buona lettura)!&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Julia è un linguaggio compilato ma funziona anche in modo interattivo.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Il CNR è anche questo: un po&#39; di codice</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2020/12/01/il-cnr-e-anche-questo-un-po-di-codice/</link>
      <pubDate>Tue, 01 Dec 2020 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2020/12/01/il-cnr-e-anche-questo-un-po-di-codice/</guid>
      <description>&lt;img src=&#34;https://imgs.xkcd.com/comics/good_code.png&#34; alt=&#34;&#34; title=&#34;XKCD, Good code&#34;&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;XKCD, &lt;a href=&#34;https://xkcd.com/844/&#34;&gt;Good code&lt;/a&gt;&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Per concludere nel miglior modo possibile questa serie di articoli (qui la &lt;a href=&#34;https://melabit.wordpress.com/2020/10/25/il-cnr-e-anche-questo-concorsi-senza-frontiere/&#34;&gt;prima&lt;/a&gt; e la &lt;a href=&#34;https://melabit.wordpress.com/2020/11/08/il-cnr-e-anche-questo-concorsi-in-latex/&#34;&gt;seconda&lt;/a&gt; parte), cosa ci può essere di meglio di un po&amp;rsquo; di codice?&lt;/p&gt;&#xA;&lt;h4 id=&#34;estrarre-il-testo-da-un-file-pdf&#34;&gt;Estrarre il testo da un file PDF&lt;/h4&gt;&#xA;&lt;p&gt;Cominciamo dallo script in R, &lt;code&gt;pdf2csv.R&lt;/code&gt;, che estrae il testo da un file PDF, (che in questo caso specifico ho usato per &lt;a href=&#34;https://melabit.wordpress.com/2020/11/08/il-cnr-e-anche-questo-concorsi-in-latex/&#34;&gt;estrarre i dati&lt;/a&gt; dalla domanda di partecipazione ad un concorso precedente). Qui sotto trovate l&amp;rsquo;immagine dello script, realizzata con &lt;a href=&#34;https://carbon.now.sh/&#34;&gt;Carbon&lt;/a&gt; (perché così è molto più bello), su GitHub c&amp;rsquo;è il &lt;a href=&#34;https://github.com/sabinomaggi/melabit/tree/main/un-po-di-codice&#34;&gt;sorgente vero e proprio&lt;/a&gt;, per chi voglia provare ad usarlo.&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2020/11/pdf2csv-1.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Per eseguire lo script è necessario aver installato sul proprio computer,  non importa se è un Mac o un PC con Linux o Windows, &lt;a href=&#34;https://www.r-project.org/&#34;&gt;l&amp;rsquo;ambiente R&lt;/a&gt; (in questo momento è disponibile la versione 4.0.3), meglio ancora se accompagnato da &lt;a href=&#34;https://rstudio.com/products/rstudio/&#34;&gt;RStudio Desktop&lt;/a&gt;, che è di gran lunga il migliore sistema integrato di sviluppo (IDE) che abbia mai usato, oltre che uno strumento efficacissimo per affacciarsi all&amp;rsquo;uso di R.&lt;/p&gt;&#xA;&lt;p&gt;Il codice è molto semplificato, ho tolto tutto ciò che non è strettamente necessario a far funzionare lo script. La chiave di tutto è la libreria &lt;a href=&#34;https://cran.r-project.org/web/packages/pdftools/index.html&#34;&gt;pdftools&lt;/a&gt; per R.  Di librerie per estrarre dati dai file PDF ne ho provate moltissime, sia per R che per Python, ma &lt;code&gt;pdftools&lt;/code&gt; le batte tutte per potenza, semplicità e velocità. Ci sono dei &lt;em&gt;tool&lt;/em&gt; che convertono un PDF in testo al ritmo di una pagina al minuto, &lt;code&gt;pdftools&lt;/code&gt; riesce a convertire (molto bene, peraltro) un file di 400 pagine &lt;a href=&#34;https://www.snpambiente.it/2018/02/24/rapporto-controlli-ambientali-del-snpa-aia-seveso-edizione-2017/&#34;&gt;come questo&lt;/a&gt; in appena 5-6 secondi. C&amp;rsquo;è altro da aggiungere?&lt;/p&gt;&#xA;&lt;p&gt;Lo script può essere utilizzato dalla linea di comando (per capirci, dal Terminale), lasciandolo esattamente com&amp;rsquo;è ed eseguendo il comando &lt;code&gt;pdf2csv.R&lt;/code&gt; seguito dal nome dal file da convertire (se il nome del file contiene degli spazi va scritto fra virgolette),&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./pdf2csv.R file-da-convertire.pdf&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;che produrrà due file &lt;code&gt;.csv&lt;/code&gt; contenenti il testo estratto dal file PDF. Il primo, con lo stesso nome del file di partenza, ha le righe numerate e cerca di riprodurre per quanto è possibile il &lt;em&gt;layout&lt;/em&gt; del file originale. Nel secondo, salvato con il suffisso &lt;code&gt;-clean&lt;/code&gt;, mancano i numeri di linea e vengono rimossi tutti gli spazi in eccesso, rendendolo più adatto ad una analisi automatica, in particolare quando il testo si estende per tutta la pagina (il primo file, invece, è molto più utile quando il testo è organizzato in colonne).&lt;/p&gt;&#xA;&lt;p&gt;Prima di usare per la prima volta &lt;code&gt;pdf2csv.R&lt;/code&gt; bisogna renderlo eseguibile tramite il comando &lt;code&gt;chmod&lt;/code&gt; (ne ho già scritto diffusamente &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;qui&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;chmod u+x pdf2csv.R&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In alternativa si può lanciare lo script tramite il comando &lt;code&gt;Rscript&lt;/code&gt; installato con R, senza che sia necessario renderlo eseguibile.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;Rscript ./pdf2csv.R file-da-convertire.pdf&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;È preferibile che il file PDF da convertire si trovi nella stessa cartella di &lt;code&gt;pdf2csv.R&lt;/code&gt;. In caso contrario il testo estratto viene comunque salvato nella cartella dove si trova la script (ve l&amp;rsquo;avevo detto che lo script era molto semplificato!).&lt;/p&gt;&#xA;&lt;p&gt;Per eseguire &lt;code&gt;pdf2csv.R&lt;/code&gt; all&amp;rsquo;interno di RStudio bisogna commentare la linea &lt;code&gt;12&lt;/code&gt; (basta aggiungere un &lt;code&gt;#&lt;/code&gt; all&amp;rsquo;inizio della riga) e attivare la riga 14 o 15 (ma solo da una delle due) togliendo il &lt;code&gt;#&lt;/code&gt; iniziale. Se si attiva la riga 14, si deve anche modificare la stringa &lt;code&gt;file-da-convertire.pdf&lt;/code&gt;, sostituendola con il nome del file da convertire. Se invece si attiva la riga numero 15, al momento dell&amp;rsquo;esecuzione dello script comparirà una finestra grafica da cui selezionare il file PDF desiderato.&lt;/p&gt;&#xA;&lt;p&gt;Nel &lt;a href=&#34;https://github.com/sabinomaggi/melabit/tree/main/un-po-di-codice&#34;&gt;repository su GitHub&lt;/a&gt; di questo articolo ho inserito dei file PDF di complessità crescente con cui fare qualche prova, fra cui un documento di quasi 1000 pagine (un vecchio manuale di riferimento del formato PDF, potevo scegliere qualcosa di diverso?), che può essere utile per valutare la velocità di conversione dello script. Non è necessario farlo a mano, il tempo di esecuzione di un qualunque programma o script si può misurare in modo preciso dal Terminale anteponendo il comando di sistema &lt;code&gt;time&lt;/code&gt;, come mostrato qui sotto.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;time ./pdf2csv.R PDFReference.pdf&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Come piccola chicca finale, ho aggiunto al repository su GitHub un file PDF contenente del testo (apparentemente) nascosto, provate a convertirlo e vi accorgerete di quanto sia banale recuperare il testo completo.&lt;/p&gt;&#xA;&lt;h4 id=&#34;generare-automaticamente-dei-documenti-con-awk&#34;&gt;Generare automaticamente dei documenti con AWK&lt;/h4&gt;&#xA;&lt;p&gt;Tirar fuori il testo contenuto in un file PDF è quasi sempre solo il primo passo del lavoro, perché quello che vogliamo veramente è filtrare il contenuto del documento mantenendo solo le informazioni che ci interessano. Nel &lt;a href=&#34;https://melabit.wordpress.com/2020/11/08/il-cnr-e-anche-questo-concorsi-in-latex/&#34;&gt;caso specifico&lt;/a&gt;, io avevo bisogno di selezionare dalla domanda di concorso precedente solo i dati relativi ad una specifica tipologia di attività (ad esempio tutti gli articoli scientifici pubblicati), salvandoli in un file &lt;em&gt;ad hoc&lt;/em&gt;. E, già che c&amp;rsquo;ero, volevo anche costruire una tabella LaTeX per ciascun articolo. Una cosa abbastanza facile da fare con &lt;a href=&#34;https://www.grymoire.com/Unix/Awk.html&#34;&gt;AWK&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Di AWK ho già parlato &lt;a href=&#34;https://melabit.wordpress.com/2019/02/18/script-per-tutti-i-giorni-entra-in-scena-awk/&#34;&gt;tempo fa&lt;/a&gt; e non mi ripeterò, dirò solo che è un linguaggio ideale per analizzare un file di testo una riga alla volta, verificando se si presentano determinate condizioni ed eseguendo le operazioni programmate corrispondenti.&lt;/p&gt;&#xA;&lt;p&gt;Nonostante i suoi tanti pregi, AWK ha una limitazione piuttosto seria: per come è strutturato, AWK deve per forza di cose esaminare tutto il file senza poter &lt;em&gt;tornare indietro&lt;/em&gt;, e quindi è piuttosto difficile fargli eseguire delle operazioni basate su condizioni multiple complesse. È molto meglio (quando è possibile) scrivere più &lt;em&gt;script&lt;/em&gt; AWK, da eseguire in sequenza sullo stesso file di partenza o sull&amp;rsquo;output generato dallo script precedente, piuttosto che cercare di combattere con le limitazioni del linguaggio, complicando a dismisura il codice.&lt;/p&gt;&#xA;&lt;p&gt;In una prima versione di questo articolo avevo pensato di utilizzare un breve estratto della mia domanda di concorso precedente per descrivere il funzionamento degli script in AWK. Ma mentre scrivevo mi sono accorto che il discorso sarebbe stato così specifico da essere quasi inutile. Ho preferito quindi preparare un piccolo file PDF tratto dagli ultimi post pubblicati su Melabit, con l&amp;rsquo;intestazione in &lt;a href=&#34;https://blog.stackpath.com/yaml/&#34;&gt;YAML&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; di ciascun post seguita dalla prima frase del testo in &lt;a href=&#34;https://daringfireball.net/projects/markdown/&#34;&gt;Markdown&lt;/a&gt; e, quando c&amp;rsquo;è, dal link all&amp;rsquo;immagine iniziale. L&amp;rsquo;ho scelto perché la struttura di questo file assomiglia moltissimo a quella della mia domanda di concorso ma, allo stesso tempo, può essere uno schema di partenza applicabile a casi più generali.&lt;/p&gt;&#xA;&lt;div style = &#34;border-style: solid; border-width: 0px 0px 0px 4px; border-color: midnightblue; background-color: aliceblue; padding: 1em;&#34;&gt;&#xA;Questo file PDF può essere considerato come la stampa di un piccolo _database_ di informazioni correlate, dove ogni post è un _record_, suddiviso a sua volta nei vari _campi_, rappresentati dalle righe di intestazione e dalla frase di testo.&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Il file PDF si chiama &lt;code&gt;Melabit ultimi post.pdf&lt;/code&gt; e, come gli altri file PDF, è disponibile nel &lt;a href=&#34;https://github.com/sabinomaggi/melabit/tree/main/un-po-di-codice&#34;&gt;repository su GitHub&lt;/a&gt; di questo articolo. Se lo aprite con Anteprima, noterete subito che ci sono delle righe vuote che separano chiaramente un post (nel linguaggio dei database, un &lt;em&gt;record&lt;/em&gt;) dall&amp;rsquo;altro. Ma convertendo il file in testo,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./pdf2csv.R &amp;#34;Melabit ultimi post.pdf&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(le virgolette sono necessarie perché il nome del file contiene degli spazi), le righe vuote scompaiono e le uniche interruzioni presenti nei due file CSV prodotti dallo script di conversione corrispondono al cambio pagina. Non so se questo sia un baco o una caratteristica voluta di &lt;code&gt;pdftools&lt;/code&gt;, ma sta di fatto che è una particolarità con la quale dobbiamo fare i conti se vogliamo analizzare il testo con AWK.&lt;/p&gt;&#xA;&lt;p&gt;Sembra una sciocchezza, ma senza le giuste interruzioni non è immediato riconoscere la fine di un record &lt;em&gt;prima&lt;/em&gt; di iniziare ad esaminare quello successivo, in modo da chiudere correttamente la tabella LaTeX corrispondente al record appena esaminato e ad aprire quella relativa al record successivo. Inoltre, mentre in questo caso specifico la struttura del file PDF è volutamente molto semplice e ripetibile, nella maggior parte dei casi reali il documento da cui estrarre i dati può contenere informazioni strutturate in modi diversi, i campi da analizzare possono essere distribuiti in modo irregolare o mancare del tutto e ci possono essere incongruenze nella loro denominazione. Gestire tutti i casi possibili con un unico script lo renderebbe rapidamente troppo complesso.&lt;/p&gt;&#xA;&lt;p&gt;Molto meglio affrontare il problema un pezzetto alla volta, utilizzando uno script specifico per ciascun tipo di informazione da estrarre (io ho avuto bisogno di 6 script AWK per eseguire tutto il lavoro di esportazione dei dati, o meglio &lt;em&gt;quasi tutto&lt;/em&gt; il lavoro, perché per i casi meno frequenti ho preferito il buon vecchio copia-incolla manuale). In fondo è la stessa logica di Unix, che mette a disposizione un gran numero di strumenti semplici che messi insieme, come tanti mattoncini Lego, riescono a fare cose incredibili.&lt;/p&gt;&#xA;&lt;p&gt;Un primo script, &lt;code&gt;addblanklines.awk&lt;/code&gt;, può servire per inserire nel file CSV di partenza una riga vuota &lt;em&gt;prima&lt;/em&gt; di ogni record (una cosa piuttosto semplice da fare in questo caso, dato che ogni post inizia sempre con la stringa &amp;ldquo;layout: post&amp;rdquo;). Lo script, appena quindici linee di codice, lo trovate &amp;ldquo;in bella&amp;rdquo; nell&amp;rsquo;immagine qui sotto (ma anche in questo caso il &lt;a href=&#34;https://github.com/sabinomaggi/melabit/tree/main/un-po-di-codice&#34;&gt;sorgente&lt;/a&gt; è su GitHub).&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2020/11/addblanklines-1.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Bastano solo due linee di codice, la #4 e la #9, per aggiungere le righe vuote al posto giusto. Ma già che ci siamo, è conveniente dare anche una &lt;em&gt;ripulita&lt;/em&gt; al file CSV togliendo le righe inutili, come quelle che contengono il numero di pagina o la stringa &lt;code&gt;---&lt;/code&gt; che segna l&amp;rsquo;inizio e la fine dell&amp;rsquo;intestazione in YAML (linee #5 e #12). Eseguendo lo script sul file CSV originale, si ottiene un nuovo file CSV con i vari record ben separati uno dall&amp;rsquo;altro.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./addblanklines.awk &amp;#34;Melabit ultimi post-clean.csv&amp;#34; &amp;gt; file-con-righe-vuote.csv&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Fatto questo, il passo successivo è semplice. Basta scansionare il file CSV appena generato, &lt;code&gt;file-con-righe-vuote.csv&lt;/code&gt;, in cerca della stringa &lt;em&gt;target&lt;/em&gt; &lt;code&gt;layout: post&lt;/code&gt; e, ogni volta che se ne trova una, generare una nuova tabella LaTeX riempiendola con i dati tratti dalle voci (o più propriamente &lt;em&gt;campi&lt;/em&gt;) successive. Il codice del secondo script, &lt;code&gt;cvs2table.awk&lt;/code&gt;, è visibile nell&amp;rsquo;immagine qui sotto (mentre il &lt;a href=&#34;https://github.com/sabinomaggi/melabit/tree/main/un-po-di-codice&#34;&gt;sorgente&lt;/a&gt; è sempre su GitHub).&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2020/11/cvs2table-1.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Lo script è relativamente lungo, sono più di 80 linee di codice, compresi commenti e righe vuote, ma una gran parte serve per implementare la funzione (linee #3-25) che riarrangia le informazioni presenti su più linee consecutive del file CSV in modo che vengano stampate su un&amp;rsquo;unica riga, e per generare la struttura di base del documento LaTeX (linee #35-42 e #83).&lt;/p&gt;&#xA;&lt;p&gt;Tolte queste, il resto del codice è semplice, si tratta più che altro di scrivere le stringe giuste al momento giusto e di tenere conto dei casi in cui le informazioni si estendono su più linee consecutive (come succede ad esempio alle linee #61-62 e #66-73). Non entrerò nei dettagli di come funziona lo script, questo non è un corso di AWK (né tantomeno di R), basterà per ora dire che è scritto in modo da essere facilmente adattato a gestire esigenze analoghe. Per usarlo, si deve eseguire lo script usando come file di input &lt;code&gt;file-con-righe-vuote.csv&lt;/code&gt; e salvando il risultato dell&amp;rsquo;elaborazione in un file LaTeX, che qui sotto ho chiamato (con la mia solita scarsa fantasia) &lt;code&gt; lista-articoli.tex&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./cvs2table.awk file-con-righe-vuote.csv &amp;gt; lista-articoli.tex&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;mettere-tutto-insieme&#34;&gt;Mettere tutto insieme&lt;/h4&gt;&#xA;&lt;p&gt;Proviamo allora ad eseguire tutti insieme gli script presentati in questo articolo, in modo da ottenere il risultato finale desiderato. Dobbiamo prima di tutto convertire il file PDF in CSV con&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./pdf2csv.R &amp;#34;Melabit ultimi post.pdf&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;che genera automaticamente il file &amp;ldquo;Melabit ultimi post-clean.csv&amp;rdquo;. Fatto questo, si eseguono in sequenza i due script AWK, salvando l&amp;rsquo;output del primo in un file intermedio.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./addblanklines.awk &amp;#34;Melabit ultimi post-clean.csv&amp;#34; &amp;gt; file-con-righe-vuote.csv&#xA;&#x9;./cvs2table.awk file-con-righe-vuote.csv &amp;gt; lista-articoli.tex&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Il risultato finale è un file LaTeX ben ordinato con una tabella per ogni articolo, come quello mostrato nella figura qui sotto la cui regolarità, messa in evidenza dai colori delle parole chiave, fa pensare ad uno spartito musicale.&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2020/11/lista-articoli-1.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Ma ha senso creare un file intermedio solo per trasferire l&amp;rsquo;output del primo script al secondo? Molto meglio usare il &lt;a href=&#34;https://www.geeksforgeeks.org/piping-in-unix-or-linux/&#34;&gt;meccanismo di &lt;em&gt;piping&lt;/em&gt;&lt;/a&gt; tipico in Unix, con il quale si può trasferire automaticamente il risultato dell&amp;rsquo;esecuzione di un comando all&amp;rsquo;ingresso di quello successivo, collegandoli con il carattere &lt;code&gt;|&lt;/code&gt; (&lt;em&gt;pipe&lt;/em&gt;)?&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; Con il &lt;em&gt;piping&lt;/em&gt;, i due comandi AWK precedenti possono essere eseguiti uno dopo l&amp;rsquo;altro in questo modo,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;./addblanklines.awk &amp;#34;Melabit ultimi post-clean.csv&amp;#34; | ./cvs2table.awk &amp;gt; lista-articoli.tex&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;evitando l&amp;rsquo;uso di un file intermedio. In questo caso non fa molta differenza, ma quando si devono trattare file molto grossi, il &lt;em&gt;piping&lt;/em&gt; è molto più efficiente (con i velocissimi dischi SSD odierni non ce ne accorgiamo più, ma ai tempi dei dischi meccanici la scrittura di grossi file sul disco era un vero collo di bottiglia) e, cosa che non guasta mai, evita di intasare il disco rigido con un gran numero di file inutili.&lt;/p&gt;&#xA;&lt;p&gt;E poi il &lt;em&gt;piping&lt;/em&gt; è un meccanismo intrinsecamente elegante, che non a caso è stato adottato anche in alcuni &lt;a href=&#34;http://leetschau.github.io/pipe-operator-in-functional-programming-languages.html&#34;&gt;linguaggi di programmazione odierni&lt;/a&gt;, come si può vedere nello script R mostrato nella prima parte di questo articolo (linee #24-25 e #35-37), dove il simbolo &lt;code&gt;|&lt;/code&gt; usato in Unix è sostituito dalla strana combinazione di caratteri &lt;code&gt;%&amp;amp;#62;%&lt;/code&gt;, piuttosto fastidiosa da scrivere con una tastiera italiana (io almeno sbaglio sempre qualcosa).&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;Chi ha l&amp;rsquo;occhio allenato si accorgerà facilmente che il file LaTeX risultante contiene alcuni errori piuttosto evidenti. Li ho lasciati apposta non solo per non complicare ulteriormente il codice, ma anche per mostrare quanto sia complicato il lavoro di estrazione automatica dei dati da file strutturati in modo non perfettamente regolare. Non è certo un caso che in questo campo ci sia una grossa attività di ricerca che prova a superare gli ostacoli e a rendere il tutto il più semplice e il più efficiente possibile.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Il comando &lt;code&gt;time&lt;/code&gt; è presente di default nei sistemi operativi Unix come Linux e macOS. Su Windows &lt;code&gt;time&lt;/code&gt; non esiste, ma si possono usare degli &lt;a href=&#34;https://qastack.it/superuser/228056/windows-equivalent-to-unix-time-command&#34;&gt;strumenti equivalenti&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;YAML è un linguaggio di &lt;em&gt;markup&lt;/em&gt; particolarmente adatto per definire dei file di configurazione e, in generale, per rappresentare informazioni strutturate in modo semplice e leggibile, molto più facile da usare di strumenti più noti come XML e JSON.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Il &lt;em&gt;piping&lt;/em&gt; è uno dei meccanismi principali che rendono Unix una specie di Lego informatico.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Imparare Python</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2020/02/16/imparare-python/</link>
      <pubDate>Sun, 16 Feb 2020 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2020/02/16/imparare-python/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2020/02/david-clode-4_ltr48nbyq-unsplash-1.jpg&#34; alt=&#34;&#34;&gt;&lt;br&gt;&#xA;&amp;ndash; &lt;em&gt;Fonte: &lt;a href=&#34;https://unsplash.com/@davidclode&#34;&gt;David Clode&lt;/a&gt; su &lt;a href=&#34;https://unsplash.com&#34;&gt;Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Di strumenti per imparare ad usare Python ce ne sono a iosa. Fra libri e corsi online come &lt;a href=&#34;http://greenteapress.com/thinkpython/html/index.html&#34;&gt;Think Python: How to Think Like a Computer Scientist&lt;/a&gt; e la relativa &lt;a href=&#34;https://runestone.academy/runestone/books/published/thinkcspy/index.html&#34;&gt;edizione interattiva&lt;/a&gt;, i più tradizionali &lt;a href=&#34;https://www.fullstackpython.com/&#34;&gt;Full Stack Python&lt;/a&gt; e &lt;a href=&#34;https://anandology.com/python-practice-book/index.html&#34;&gt;Python Practice Book&lt;/a&gt;, o il corso online del MIT &lt;a href=&#34;https://www.edx.org/course/introduction-to-computer-science-and-programming-7&#34;&gt;Introduction to Computer Science and Programming Using Python&lt;/a&gt;, c&amp;rsquo;è solo l&amp;rsquo;imbarazzo della scelta.&lt;/p&gt;&#xA;&lt;p&gt;E poi, quando si inizia a masticare i rudimenti del linguaggio, c&amp;rsquo;è il favoloso &lt;a href=&#34;http://pythontutor.com/&#34;&gt;Python Tutor&lt;/a&gt;, che mostra in modo interattivo quello che succede quando si esegue ogni singola linea di codice.&lt;/p&gt;&#xA;&lt;p&gt;Senza dimenticare &lt;a href=&#34;https://realpython.com/&#34;&gt;Real Python&lt;/a&gt;, che negli ultimi anni è diventato il sito di riferimento per il programmatore in Python, pieno di tutorial scritti benissimo, utili sia per il programmatore alle prime armi che per il professionista scafato che passa le giornate (e spesso anche le notti) davanti al monitor del computer. Il professionista non può farsi farsi sfuggire anche &lt;a href=&#34;https://www.thepythoncorner.com/&#34;&gt;The Python Corner&lt;/a&gt;, un sito scritto in inglese (come tutti gli altri citati qui) ma italiano al 100%, e nemmeno &lt;a href=&#34;https://realpython.com/products/python-tricks-book/&#34;&gt;Python Tricks: The Book&lt;/a&gt;, un libro pieno di trucchi fantastici, indispensabili per utilizzare Python al pieno delle sue potenzialità.&lt;/p&gt;&#xA;&lt;p&gt;Insomma, per imparare Python non c&amp;rsquo;è che l&amp;rsquo;imbarazzo della scelta.&lt;/p&gt;&#xA;&lt;hr style = &#34;border: none; &#xA;            border-top: 3px double #333; &#xA;            color: #333; &#xA;            overflow: visible; &#xA;            height: 5px; &#xA;            width: 50%; &#xA;            margin-left: auto; &#xA;            margin-right: auto;&#34;&#xA;&gt;&#xA;&#xA;&lt;p&gt;Ma la chicca me la sono lasciata per ultimo. Perché c&amp;rsquo;è &lt;a href=&#34;https://twitter.com/chris_swenson/status/1225836060938125313&#34;&gt;chi non si accontenta&lt;/a&gt; di tutto questo ben di Dio e tanto fa che &lt;a href=&#34;https://www.zdnet.com/article/python-programming-language-now-you-can-take-nsas-free-course-for-beginners/&#34;&gt;riesce ad avere accesso&lt;/a&gt; al corso di Python utilizzato internamente dalla NSA, l&amp;rsquo;agenzia USA che si occupa della raccolta e dell&amp;rsquo;elaborazione di dati e informazioni da tutto il mondo, nonché della sicurezza delle reti di comunicazione degli Stati Uniti. Evidentemente anche alla NSA pensano che Python sia un linguaggio di programmazione molto ben fatto, e ora anche noi comuni cittadini possiamo renderci conto di come l&amp;rsquo;insegnano, scaricando il &lt;a href=&#34;https://archive.org/details/comp3321&#34;&gt;corso introduttivo alla programmazione in Python&lt;/a&gt; scritto dai loro stessi insegnanti.&lt;/p&gt;&#xA;&lt;p&gt;Non so voi, ma io sono curioso di dargli una occhiata. E poi è bello sapere che c&amp;rsquo;è in giro qualcuno molto più tignoso di me!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Buon Natale dal Terminale</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2019/12/25/buon-natale-dal-terminale/</link>
      <pubDate>Wed, 25 Dec 2019 00:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2019/12/25/buon-natale-dal-terminale/</guid>
      <description>&lt;p&gt;C&amp;rsquo;è gente che con il Terminale sarebbe in grado di far volare un Boeing. Oppure che sa costruire un &lt;a href=&#34;https://github.com/sergiolepore/ChristBASHTree&#34;&gt;alberello di Natale pieno di lucine colorate&lt;/a&gt;, come questo.&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2019/12/buon-natale-2019.gif&#34; alt=&#34;&#34;&gt;&lt;p&gt;Se lo volete anche voi, vi basta aprire il Terminale ed eseguire&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ curl https://raw.githubusercontent.com/sergiolepore/ChristBASHTree/master/tree-EN.sh | bash&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;oppure, se preferite la versione tradotta in italiano,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ curl https://raw.githubusercontent.com/sabinomaggi/ChristBASHTree/master/tree-IT.sh | bash&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(come sempre il &lt;code&gt;$&lt;/code&gt; rappresenta il prompt del terminale e non fa parte del comando).&lt;/p&gt;&#xA;&lt;p style=&#34;text-align:center; color:#1abc9c; font-size:250%; font-family:cursive;&#34;&gt;Buon Natale!!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: lo script è il comando</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2019/04/12/script-per-tutti-i-giorni-lo-script-e-il-comando/</link>
      <pubDate>Fri, 12 Apr 2019 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2019/04/12/script-per-tutti-i-giorni-lo-script-e-il-comando/</guid>
      <description>&lt;img src=&#34;http://storage.datormuseum.se/u/96935524/Datormusuem/VT50/VT50-RT11-small.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Nelle puntate precedenti abbiamo visto come scrivere dei semplici script in &lt;code&gt;bash&lt;/code&gt; o in &lt;code&gt;awk&lt;/code&gt; che risolvono un problema assai specifico, è vero, ma che possono anche costituire una buona base di partenza per affrontare argomenti più complessi (i link alle puntate precedenti si trovano alla fine dell&amp;rsquo;articolo).&lt;/p&gt;&#xA;&lt;p&gt;In particolare, nella &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;terza puntata&lt;/a&gt; abbiamo imparato come rendere i nostri script &lt;em&gt;quasi&lt;/em&gt; indistinguibili dai normali comandi del Terminale: (1) si aggiunge in testa allo script lo &lt;a href=&#34;https://en.wikipedia.org/wiki/Shebang_%28Unix%29&#34;&gt;shebang&lt;/a&gt;, cioè la sequenza di caratteri &lt;code&gt;#!&lt;/code&gt;, seguita dal percorso completo al programma da utilizzare per eseguire lo script,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; (2) si usa il comando &lt;code&gt;chmod&lt;/code&gt; per rendere lo script eseguibile (almeno) all’utente attuale del Mac,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u+x nomescript&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove &lt;code&gt;nomescript&lt;/code&gt; è il nome generico dello script che vogliamo rendere eseguibile (ad esempio lo script &lt;code&gt;convert_title.sh&lt;/code&gt; della &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;terza puntata&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Il &amp;ldquo;quasi&amp;rdquo; di prima dipende dal fatto che, anche con queste modifiche, ogni volta che eseguiamo lo script dobbiamo indicare esplicitamente la directory dove si trova. Ad esempio, se ci siamo spostati con &lt;code&gt;cd&lt;/code&gt; nella directory che contiene &lt;code&gt;nomescript&lt;/code&gt;, per eseguirlo script dobbiamo scrivere&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ./nomescript&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;premettendo quindi al nome dello script il percorso (&lt;code&gt;./&lt;/code&gt;) alla directory corrente.&lt;/p&gt;&#xA;&lt;p&gt;Invece, quando eseguiamo uno dei comandi del sistema operativo, ci basta scrivere il nome del comando nel Terminale e il sistema operativo (o più precisamente la &lt;a href=&#34;https://it.wikipedia.org/wiki/Shell_Unix&#34;&gt;shell&lt;/a&gt; che stiamo usando, che in genere è &lt;code&gt;bash&lt;/code&gt;)&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; va a cercare il programma sul disco rigido e lo esegue senza troppi problemi.&lt;/p&gt;&#xA;&lt;p&gt;Qual&amp;rsquo;è il meccanismo che permette alla shell di &lt;em&gt;sapere&lt;/em&gt; in quale directory si trovano i comandi che eseguiamo nel Terminale? Esiste un modo per replicare questo comportamento anche per i nostri script, rendendoli praticamente indistinguibili dai comandi intrinseci del sistema operativo?&lt;/p&gt;&#xA;&lt;h4 id=&#34;variabili-di-ambiente&#34;&gt;Variabili di ambiente&lt;/h4&gt;&#xA;&lt;p&gt;In realtà non c&amp;rsquo;è niente di sofisticato o di particolarmente intelligente in quello che fa la shell. La chiave di tutto sta nelle &lt;a href=&#34;https://it.wikipedia.org/wiki/Variabile_d%27ambiente_%28Unix%29&#34;&gt;variabili di ambiente&lt;/a&gt; di &lt;code&gt;bash&lt;/code&gt;, delle variabili speciali usate fra l&amp;rsquo;altro per specificare le impostazioni di lavoro della shell. Se lanciamo il Terminale ed eseguiamo il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ env&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;otterremo un lungo elenco con tutte le variabili di ambiente definite da &lt;code&gt;bash&lt;/code&gt;, che per convenzione vengono scritte in maiuscolo. Fra queste spiccano &lt;code&gt;HOME&lt;/code&gt;, che definisce il percorso alla cartella Home dell&amp;rsquo;utente che sta usando il Mac, &lt;code&gt;USER&lt;/code&gt; che riporta il &lt;code&gt;nome account&lt;/code&gt; (o &lt;code&gt;nome breve&lt;/code&gt;) dell&amp;rsquo;utente, e &lt;code&gt;PWD&lt;/code&gt; che contiene il percorso alla directory in cui ci troviamo (percorso che, come già visto, &lt;a href=&#34;https://melabit.wordpress.com/2019/01/30/script-per-tutti-i-giorni-ricapitoliamo/&#34;&gt;si può ricavare&lt;/a&gt; con il comando &lt;code&gt;pwd&lt;/code&gt;, ma guarda la combinazione).&lt;/p&gt;&#xA;&lt;p&gt;Se siamo interessati solo ad una particolare variabile di ambiente, possiamo stamparla con &lt;code&gt;echo&lt;/code&gt; seguito dal nome della variabile di ambiente, che però deve essere preceduto dal simbolo &lt;code&gt;$&lt;/code&gt;. Ad esempio&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo $HOME&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;stampa nel Terminale il valore della variabile di ambiente &lt;code&gt;HOME&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Fra tutte le variabili di ambiente elencate da &lt;code&gt;env&lt;/code&gt;, quella che ci interessa di più in questo momento è &lt;code&gt;PATH&lt;/code&gt;, che contiene una serie di percorsi di directory separati dal simbolo &lt;code&gt;:&lt;/code&gt;. Nella configurazione di default il valore del PATH è&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo $PATH&#xA;PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h4 id=&#34;shell-e-path&#34;&gt;Shell e PATH&lt;/h4&gt;&#xA;&lt;p&gt;È proprio il PATH che permette alla shell di trovare da sola i comandi di sistema. Ogni volta che eseguiamo un comando nel Terminale, la shell lo cerca nelle directory indicate nel PATH, esaminandole una dopo l&amp;rsquo;altra nell&amp;rsquo;ordine in cui sono scritte. Se trova il comando lo esegue immediatamente, senza preoccuparsi di esaminare le directory successive, altrimenti dà un errore di &lt;code&gt;command not found&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Di conseguenza, l&amp;rsquo;ordine in cui sono elencati i percorsi nel PATH è importante. Questa particolarità può essere sfruttata per sostituire un comando del sistema operativo con una versione più recente, senza però cancellare il comando originale: se il comando originale è situato in &lt;code&gt;/usr/bin&lt;/code&gt; o in &lt;code&gt;/bin&lt;/code&gt;, basta installare la versione aggiornata in una directory del PATH che precede queste due directory, come ad esempio &lt;code&gt;/usr/local/bin&lt;/code&gt; (che nei sistemi Unix serve proprio per installare il software &amp;ldquo;locale&amp;rdquo; non gestito direttamente dal sistema operativo).&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;La seconda conseguenza è che, se modifichiamo il PATH aggiungendo altre directory in testa o in fondo all&amp;rsquo;elenco originale, possiamo &lt;em&gt;obbligare&lt;/em&gt; la shell a cercare i comandi anche in queste nuove directory non presenti nella configurazione di default. Che è proprio quello che ci serve.&lt;/p&gt;&#xA;&lt;p&gt;Prima di andare avanti una avvertenza &lt;strong&gt;FONDAMENTALE&lt;/strong&gt;. Possiamo aggiungere senza troppi problemi delle nuove directory al PATH di default, ma non dobbiamo &lt;strong&gt;MAI MAI MAI&lt;/strong&gt; rimuovere le directory presenti nella configurazione originale del PATH, in particolare le quattro directory &lt;code&gt;/usr/bin:/bin:/usr/sbin:/sbin&lt;/code&gt; (leggetele ad alta voce e notate l&amp;rsquo;assonanza). Cancellare per errore una di queste directory dal PATH significa non poter più usare il Mac, o perlomeno dover usare degli strumenti non alla portata di tutti per rimettere a posto le cose.&lt;/p&gt;&#xA;&lt;p&gt;Siete avvertiti!!!&lt;/p&gt;&#xA;&lt;h4 id=&#34;modificare-il-path&#34;&gt;Modificare il PATH&lt;/h4&gt;&#xA;&lt;p&gt;Per aggiungere (o rimuovere) delle directory al PATH di default del nostro Mac dobbiamo modificare con un &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;editor di testo&lt;/a&gt; (non con un wordprocessor!) il file &lt;code&gt;.bashrc&lt;/code&gt; situato nella nostra &lt;code&gt;HOME&lt;/code&gt;. Questo introduce una piccola complicazione, perché il file &lt;code&gt;~/.bashrc&lt;/code&gt; è un file nascosto, non accessibile direttamente dal Finder.&lt;/p&gt;&#xA;&lt;p&gt;Se usiamo &lt;code&gt;emacs&lt;/code&gt; o &lt;code&gt;vi&lt;/code&gt; possiamo aprire &lt;code&gt;.bashrc&lt;/code&gt; direttamente dal Terminale. Ci basta spostarci nella &lt;code&gt;HOME&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ed eseguire&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ emacs .bashrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;oppure&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ vi .bashrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Se questi editor ci sembrano troppo difficili da usare (e lo sono!), possiamo usare &lt;code&gt;nano&lt;/code&gt; che, come &lt;code&gt;emacs&lt;/code&gt; e &lt;code&gt;vi&lt;/code&gt;, si trova installato di default su ogni Mac&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ nano .bashrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Anche se &lt;a href=&#34;https://www.nano-editor.org/&#34;&gt;nano&lt;/a&gt; è un editor piuttosto limitato rispetto ai due mostri sacri, è molto comodo per modificare velocemente i file di sistema senza dover affrontare una lunga fase di apprendimento.&lt;/p&gt;&#xA;&lt;p&gt;Se invece preferiamo usare un &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;editor grafico&lt;/a&gt; come BBEdit, TextMate, Atom o simili, la procedura esatta per aprire un file nascosto dipende dall&amp;rsquo;editor scelto.&lt;/p&gt;&#xA;&lt;p&gt;Alcuni editor permettono di installare un comando di Terminale con cui lanciare l&amp;rsquo;editor dalla linea di comando: &lt;code&gt;mate&lt;/code&gt; per TextMate, &lt;code&gt;atom&lt;/code&gt; e &lt;code&gt;bbedit&lt;/code&gt; per&amp;hellip; lo sapete già. Anche con questi editor, quindi, possiamo aprire &lt;code&gt;.bashrc&lt;/code&gt; dal Terminale con uno dei comandi seguenti&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ mate .bashrc &#xA;$ atom .bashrc&#xA;$ bbedit .bashrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Con BBEdit e TextMate, la finestra di apertura file dispone di un tasto &lt;code&gt;Opzioni&lt;/code&gt; con il quale si può decidere di mostrare (e quindi di aprire) anche i file nascosti&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2019/04/textmate-options.png&#34; alt=&#34;&#34;&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2019/04/textmate-hidden.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Ma il metodo più generale per modificare un file nascosto con un editor grafico è quello di usare il comando &lt;code&gt;open&lt;/code&gt; dal Terminale&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~&#xA;$ open -a &amp;quot;TextMate&amp;quot; .bashrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove l&amp;rsquo;opzione &lt;code&gt;-a&lt;/code&gt; permette di specificare l&amp;rsquo;applicazione con cui aprire il file indicato.&lt;/p&gt;&#xA;&lt;p&gt;Qualunque sia il metodo utilizzato, alla fine ci ritroveremo con il file &lt;code&gt;.bashrc&lt;/code&gt; pronto per essere modificato. Tutto quello che dobbiamo fare è aggiungere questa linea alla fine di &lt;code&gt;.bashrc&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export PATH=$PATH:~/Development&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;che istruisce la shell di andare a cercare i comandi da eseguire nel Terminale anche nella directory &lt;code&gt;~/Development&lt;/code&gt;, dove &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;abbiamo deciso di salvare&lt;/a&gt; tutti gli script che sviluppiamo.&lt;/p&gt;&#xA;&lt;p&gt;Una volta fatta questa semplice modifica, salviamo il file &lt;code&gt;.bashrc&lt;/code&gt; e usciamo dall&amp;rsquo;editor. Chiudiamo e riapriamo il Terminale per &lt;em&gt;costringere&lt;/em&gt; la shell a rileggere il file &lt;code&gt;.bashrc&lt;/code&gt; (oppure eseguiamo il comando &lt;code&gt;$ source ~/.bashrc&lt;/code&gt; senza chiudere il Terminale) e proviamo di nuovo ad eseguire &lt;code&gt;nomescript&lt;/code&gt;, ma questa volta senza premettere il percorso alla directory dove si trova&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ nomescript&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Questa volta lo script funzionerà senza bisogno di &lt;em&gt;aiutini&lt;/em&gt;, proprio come se fosse un normale comando di sistema. Per verificare che tutto funzioni come descritto possiamo provare ad eseguire uno degli script della &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;terza&lt;/a&gt; o della &lt;a href=&#34;https://melabit.wordpress.com/2019/02/18/script-per-tutti-i-giorni-entra-in-scena-awk/&#34;&gt;quinta&lt;/a&gt; puntata.&lt;/p&gt;&#xA;&lt;h4 id=&#34;ma-non-è-ancora-finita&#34;&gt;Ma non è ancora finita&amp;hellip;&lt;/h4&gt;&#xA;&lt;p&gt;Bisogna ammetterlo, aggiungere al &lt;code&gt;$PATH&lt;/code&gt; una directory &lt;em&gt;qualunque&lt;/em&gt; come &lt;code&gt;~/Development&lt;/code&gt; può andar bene per fare delle prove veloci, ma non è per niente elegante. Sarebbe molto meglio adeguarsi alle convenzioni di Unix, secondo le quali i programmi eseguibili devono trovarsi in una directory denominata &lt;code&gt;bin&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Niente di più facile, possiamo creare facilmente una directory &lt;code&gt;bin&lt;/code&gt; nella nostra &lt;code&gt;HOME&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd&#xA;$ mkdir bin&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e decidere di tenere gli script in fase di sviluppo nella directory &lt;code&gt;~/Development&lt;/code&gt;, per poi spostarli (o meglio copiarli) in &lt;code&gt;~/bin&lt;/code&gt; quando sono pronti per essere usati. Naturalmente dovremo modificare di conseguenza il file &lt;code&gt;.bashrc&lt;/code&gt;, aggiungendo alla fine del file&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export PATH=$PATH:~/bin&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;al posto di &lt;code&gt;export PATH=$PATH:~/Development&lt;/code&gt; visto sopra.&lt;/p&gt;&#xA;&lt;p&gt;Non ci piace vedere con il Finder la directory &lt;code&gt;bin&lt;/code&gt; nella &lt;code&gt;HOME&lt;/code&gt;? Possiamo nasconderla con facilità, basta solo eseguire dal solito Terminale il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chflags hidden ~/bin&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;(il comando duale &lt;code&gt;$ chflags nohidden ~/bin&lt;/code&gt; rende di nuovo visibile la directory).&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;Per i più pigri che non vogliono andare a rileggere le puntate precedenti per provare le novità descritte nell&amp;rsquo;articolo, ecco un semplice script in &lt;code&gt;bash&lt;/code&gt; che mostra la data e l&amp;rsquo;ora corrente nel formato standard Unix e in una forma molto più dettagliata (e per una volta anche nella nostra lingua)&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash&#xA;&#xA;year=`date +%Y`&#xA;month=`date +%B`&#xA;day=`date +%d`&#xA;hour=`date +%H`&#xA;minute=`date +%M`&#xA;second=`date +%S`&#xA;dayofyear=`date +%j`&#xA;weekday=`date +%A`&#xA;&#xA;echo `date`&#xA;echo -n &amp;#34;Oggi è $weekday $day $month $year, &amp;#34;&#xA;echo -n &amp;#34;il $dayofyear-esimo giorno dell&amp;#39;anno, &amp;#34;&#xA;echo &amp;#34;e sono le ore $hour:$minute:$second&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copiamo lo script nell&amp;rsquo;editor preferito, salviamolo in &lt;code&gt;~/bin&lt;/code&gt; (o in &lt;code&gt;~/Development&lt;/code&gt;) con il nome &lt;code&gt;data_estesa&lt;/code&gt;, rendiamolo eseguibile con &lt;code&gt;chmod&lt;/code&gt; e proviamo che funzioni come previsto&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ data_estesa&#xA;Fri Apr 12T17:28:00:50 CEST 2019&#xA;Oggi è Venerdì 12 Aprile 2019, il 102-esimo giorno dell&#39;anno, e sono le ore 17:28:50&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;E per oggi è davvero tutto.&lt;/p&gt;&#xA;&lt;h4 id=&#34;articoli-precedenti&#34;&gt;Articoli precedenti&lt;/h4&gt;&#xA;&lt;p&gt;Per leggere gli articoli precedenti della serie basta cliccare sui link qui sotto.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Prima puntata, &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;Script per tutti i giorni: semplici modifiche alle stringhe di testo&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Seconda puntata, &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;Script per tutti i giorni: dalla linea di comando al programma&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Terza puntata, &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;Script per tutti i giorni: shell e parametri&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Quarta puntata, &lt;a href=&#34;https://melabit.wordpress.com/2019/01/30/script-per-tutti-i-giorni-ricapitoliamo/&#34;&gt;Script per tutti i giorni: ricapitoliamo&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Quinta puntata, &lt;a href=&#34;https://melabit.wordpress.com/2019/02/18/script-per-tutti-i-giorni-entra-in-scena-awk/&#34;&gt;Script per tutti i giorni: entra in scena awk&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Sul Mac uno script in &lt;code&gt;bash&lt;/code&gt; richiede il percorso &lt;code&gt;/bin/bash&lt;/code&gt;, uno in &lt;code&gt;awk&lt;/code&gt; &lt;em&gt;puro&lt;/em&gt; &lt;code&gt;/usr/bin/awk&lt;/code&gt;, mentre uno nella ormai veneranda versione 2.7 di &lt;code&gt;python&lt;/code&gt; installata di default in macOS richiede &lt;code&gt;/usr/bin/python&lt;/code&gt; (ma ci vuol poco ad installare &lt;code&gt;python3&lt;/code&gt; con &lt;a href=&#34;https://brew.sh&#34;&gt;Homebrew&lt;/a&gt; o &lt;a href=&#34;https://conda.io/en/latest/&#34;&gt;Conda&lt;/a&gt;).&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Ma ci sono anche &lt;code&gt;zsh&lt;/code&gt;, &lt;code&gt;ksh&lt;/code&gt;, &lt;code&gt;tcsh&lt;/code&gt;, &lt;code&gt;fish&lt;/code&gt;, solo per menzionare le shell più note.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;È esattamente quello che fa &lt;a href=&#34;https://brew.sh&#34;&gt;Homebrew&lt;/a&gt;, uno strumento utilissimo (di cui ho &lt;a href=&#34;https://melabit.wordpress.com/2014/04/29/homebrew-software-per-il-mac-fatto-in-casa/&#34;&gt;scritto parecchio&lt;/a&gt; su questo blog) che utilizza &lt;code&gt;/usr/local/bin&lt;/code&gt; per installare un gran numero di strumenti software provenienti dal mondo Linux e non disponibili su macOS, oppure per aggiornare a versioni più recenti quelli, normalmente piuttosto datati, forniti da Apple insieme al sistema operativo.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: entra in scena awk</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2019/02/18/script-per-tutti-i-giorni-entra-in-scena-awk/</link>
      <pubDate>Mon, 18 Feb 2019 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2019/02/18/script-per-tutti-i-giorni-entra-in-scena-awk/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://www.viscountinstruments.it/wp-content/uploads/2020/01/ebano_3-600x433.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; &lt;em&gt;&lt;a href=&#34;https://www.viscountinstruments.it/instrument/a-w-k-keyboard/&#34;&gt;Tastiera A.W.K., Viscount Instruments&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Nelle prime tre puntate di questa serie abbiamo imparato a scrivere uno script in &lt;code&gt;bash&lt;/code&gt; per trasformare una stringa di testo in modo che segua delle  convenzioni ben determinate a priori (qui i link alla &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;prima&lt;/a&gt;, &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;seconda&lt;/a&gt; e &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;terza&lt;/a&gt; puntata).&lt;/p&gt;&#xA;&lt;p&gt;In questo caso particolare, la stringa risultante dalla trasformazione deve essere scritta tutta in minuscolo e non deve contenere apostrofi o altri caratteri speciali, a parte il trattino usato come separatore di parole. L&amp;rsquo;idea è quella di usare questa stringa, insieme alla data di pubblicazione del post, per dare un nome standard e facilmente rintracciabile al file Markdown che contiene il testo del post stesso, &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;utilizzando il formato&lt;/a&gt; &lt;code&gt;YYYY-MM-DD-titolo-del-post.md&lt;/code&gt;, dove &lt;code&gt;YYYY&lt;/code&gt; indica l’anno, &lt;code&gt;MM&lt;/code&gt; il mese e &lt;code&gt;DD&lt;/code&gt; il giorno di pubblicazione.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;approccio &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;seguito finora&lt;/a&gt; è utile per imparare i fondamenti della programmazione in &lt;code&gt;bash&lt;/code&gt;, ma manca decisamente di praticità. Partire dal titolo e dalla data di pubblicazione presenti nell&amp;rsquo;intestazione del post per arrivare al nome completo del file richiede un certo lavoro di copia e incolla fra l&amp;rsquo;editor, il Finder e il Terminale, e gli errori sono sempre in agguato.&lt;/p&gt;&#xA;&lt;p&gt;Quello che ci vuole è uno script che renda il processo completamente automatico, rinominando il file Markdown a partire dal contenuto del documento stesso.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Si potrebbe benissimo fare anche con &lt;code&gt;bash&lt;/code&gt;, ma perché complicarsi la vita quando c&amp;rsquo;è uno strumento fatto apposta per analizzare ed estrarre dei dati dai file di testo?&lt;/p&gt;&#xA;&lt;h4 id=&#34;awk-questo-sconosciuto&#34;&gt;AWK, questo sconosciuto&lt;/h4&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/onetrueawk/awk&#34;&gt;AWK&lt;/a&gt; è un linguaggio di programmazione interpretato sviluppato negli anni &amp;lsquo;70 presso i &lt;a href=&#34;https://it.wikipedia.org/wiki/Bell_Laboratories&#34;&gt;Bell Labs&lt;/a&gt;, il famosissimo centro di ricerca americano che ci ha dato il transistor, il laser, Unix e il C (e moltissimo altro). AWK è stato sviluppato da Alfred Aho, Peter Weinberger e Brian Kernighan, tre grandi studiosi di &lt;em&gt;computer science&lt;/em&gt;, fra i quali spicca il terzo, coautore insieme a Dennis Ritchie di &lt;a href=&#34;https://archive.org/stream/CProgLangBooksCollection/1_TheCProgLang-2ndEd-RitchieKernighan#page/n17/mode/2up&#34;&gt;The C Programming Language&lt;/a&gt;, il volume di riferimento sul linguaggio C, noto anche semplicemente come &amp;ldquo;K&amp;amp;R&amp;rdquo; dai cognomi dei due autori.&lt;/p&gt;&#xA;&lt;p&gt;Alla base di AWK c&amp;rsquo;è l&amp;rsquo;idea di elaborare un file di testo una riga alla volta, controllando che la riga in esame soddisfi una o più condizioni prestabilite ed eseguendo le azioni programmate per ciascuna di queste condizioni&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    condizione #1: {azione #1}&#xA;    condizione #2: {azione #2}&#xA;    ...&#xA;    condizione #N: {azione #N}   &#xA;    &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Per AWK un file di testo è costituito da un certo numero di righe (&lt;em&gt;record&lt;/em&gt;), ciascuna delle quali è suddivisa in uno o più campi (&lt;em&gt;field&lt;/em&gt;), separati fra loro da un &lt;em&gt;separatore di campo&lt;/em&gt;, che di default è lo spazio ma che può essere modificato a piacere. Per riferirsi a ciascun campo AWK usa le variabili speciali &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt; e così via, dove il numero indica la posizione del campo all&amp;rsquo;interno della riga. La variabile &lt;code&gt;$0&lt;/code&gt; contiene l&amp;rsquo;intera riga corrente.&lt;/p&gt;&#xA;&lt;p&gt;Tutto qui? Più o meno. C&amp;rsquo;è (quasi) solo da aggiungere che AWK prevede due azioni speciali opzionali, racchiuse fra i blocchi &lt;code&gt;BEGIN {...}&lt;/code&gt;, &lt;code&gt;END {...}&lt;/code&gt;, che servono per eseguire le operazioni preliminari e conclusive necessarie per il buon funzionamento del programma, ad esempio per definire il separatore di campo. Un programma completo in AWK ha quindi una struttura di questo tipo,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    BEGIN { istruzione&#xA;            istruzione&#xA;            ....&#xA;          }&#xA;    &#xA;    condizione #1: { istruzione&#xA;                     istruzione&#xA;                     ....&#xA;                   }&#xA;    condizione #2: { istruzione&#xA;                     istruzione&#xA;                     ....&#xA;                   }&#xA;&#xA;    ...&#xA;    condizione #N: { istruzione&#xA;                     istruzione&#xA;                     istruzione&#xA;                     ....&#xA;                   }&#xA;&#xA;     END { istruzione&#xA;           istruzione&#xA;           ....&#xA;         }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;dove come già detto i blocchi &lt;code&gt;BEGIN {...}&lt;/code&gt;, &lt;code&gt;END {...}&lt;/code&gt; sono opzionali.&lt;/p&gt;&#xA;&lt;p&gt;Nonostante la fama dei suoi autori, AWK è poco utilizzato, molto meno di quanto meriterebbe, i programmatori del mondo UNIX preferiscono usare strumenti più semplici ma meno potenti come &lt;code&gt;sed&lt;/code&gt; (che abbiamo già incontrato nelle &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;puntate&lt;/a&gt; &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;precedenti&lt;/a&gt;) o il declinante &lt;code&gt;perl&lt;/code&gt;, un linguaggio di manipolazione di file di testo perfetto per i programmatori che mitizzano Tafazzi.&lt;/p&gt;&#xA;&lt;p&gt;AWK invece ha il giusto equilibrio di potenza e semplicità d&amp;rsquo;uso ed è uno strumento perfetto se gli si chiede di fare quello per cui è stato ideato, elaborare informazioni strutturate contenute in file di testo.&lt;/p&gt;&#xA;&lt;p&gt;Per fortuna AWK è installato di default in macOS e in Linux, oltre che in tutti i sistemi operativi basati su UNIX che si trovano in giro, per cui per provarlo basta lanciare il Terminale ed eseguire il comando &lt;code&gt;awk&lt;/code&gt;. In realtà ci sono in giro almeno due versioni diverse di AWK. In macOS è installato &lt;code&gt;awk&lt;/code&gt; &lt;em&gt;liscio&lt;/em&gt;, la versione del linguaggio definita dai tre autori originali nel volume &lt;a href=&#34;https://archive.org/details/pdfy-MgN0H1joIoDVoIC7&#34;&gt;The AWK programming language&lt;/a&gt;. Su Linux, invece, si trova in genere &lt;code&gt;gawk&lt;/code&gt;, una &lt;a href=&#34;https://www.gnu.org/software/gawk/manual/&#34;&gt;implementazione&lt;/a&gt; del linguaggio della Free Software Foundation pienamente compatibile con &lt;code&gt;awk&lt;/code&gt;, a cui sono state aggiunte alcune estensioni piuttosto utili. Installare &lt;code&gt;gawk&lt;/code&gt; su macOS è facile per chi usa &lt;a href=&#34;https://melabit.wordpress.com/2014/04/29/homebrew-software-per-il-mac-fatto-in-casa/&#34;&gt;Homebrew&lt;/a&gt;, dal Terminale&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ brew install gawk&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Da ora in poi per semplicità farò cadere la distinzione fatta finora fra AWK, il linguaggio di programmazione, e &lt;code&gt;awk&lt;/code&gt;, l&amp;rsquo;interprete del linguaggio, usando sempre e solo il termine awk per riferirmi ad entrambi.&lt;/p&gt;&#xA;&lt;h4 id=&#34;un-programma-banale-in-awk&#34;&gt;Un programma banale in awk&lt;/h4&gt;&#xA;&lt;p&gt;Per avere una idea di cosa può fare awk, ecco un piccolissimo (e rozzo) programma di esempio,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BEGIN { FS = &amp;#34;,&amp;#34;&#xA;        OFS = &amp;#34;, &amp;#34;&#xA;      }&#xA;&#xA;$1 ~ /Violanda/ { $1 = &amp;#34;Jolanda&amp;#34; }&#xA;                { print $2, $1, $3, $6, $4, $5 }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;che applicato ad un elenco di indirizzi come questo,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOME,COGNOME,INDIRIZZO,LOCALITA,PROVINCIA,CAP&#xA;Massino,Nardini,Via Roma 8,Grana,AT,14031&#xA;Primo,Sabbatini,Via C. Cattaneo 50,Cala di Volpe,SS,07020&#xA;Giuseppe,Marino,Via C. Alberto 75,Barni,CO,22030&#xA;Ivano,Costa,Via Guantai Nuovi 29,Ischia,NA,80077&#xA;Margherita,Davide,Via Nuova Agnano 83,Rufina,FI,50068&#xA;Daphne,Lettiere,Via R. Conforti 67,Castel Di Ieri,AQ,67020&#xA;Violanda,Lori,Via A. Manzoni 101,Parona,PV,27020&#xA;Luigia,Cremonesi,Via Castelfidardo 145,Cittadella Del Capo,CS,87020&#xA;Fiore,Mucciano,Via Valpantena 120,Buccino Stazione,SA,84020&#xA;Sandra,Greco,Via Pisanelli 140,Castiglione D&amp;#39;Adda,LO,26823&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;scambia la posizione del nome e del cognome e sposta il CAP prima della Località in tutte le righe del file. Già che c&amp;rsquo;è, corregge anche il nome sbagliato &amp;ldquo;Violanda&amp;rdquo; e lo trasforma in &amp;ldquo;Jolanda&amp;rdquo;. Nella riga #5, &lt;code&gt;$1 ~ /Violanda/&lt;/code&gt; è la condizione, e &lt;code&gt;{$1 = &amp;quot;Jolanda&amp;quot;}&lt;/code&gt; l&amp;rsquo;azione relativa, mentre nella riga #6 la condizione è vuota e quindi l&amp;rsquo;azione conseguente &lt;code&gt;{print $2, $1, $3, $6, $4, $5}&lt;/code&gt; si applica a tutte le righe del file. Il blocco &lt;code&gt;BEGIN {...}&lt;/code&gt; serve per definire il carattere (o i caratteri) che separa i campi contenuti in ciascuna riga letta o scritta dal programma: la variabile predefinita &lt;code&gt;FS&lt;/code&gt; è il separatore dei campi del file di input (quello letto dal programma), &lt;code&gt;OFS&lt;/code&gt; è il separatore dei campi delle righe stampate dallo script.&lt;/p&gt;&#xA;&lt;p&gt;Per provarlo, copiate il programma in un editor e salvatelo come &lt;code&gt;swap.awk&lt;/code&gt;, poi copiate la lista di indirizzi e salvatela come &lt;code&gt;address.csv&lt;/code&gt; (meglio se salvate i due file nella cartella &lt;code&gt;~/Development&lt;/code&gt;, &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;ricordate&lt;/a&gt;?). Infine lanciate il Terminale, eseguite il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ awk -f swap.awk address.csv &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e vedete cosa viene fuori. Provate a cambiare &lt;code&gt;OFS&lt;/code&gt; e a vedere che succede.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Domanda 1: Come si fa a lanciare lo script senza dover premettere il comando &lt;code&gt;awk&lt;/code&gt;?&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Domanda 2: Se si rimuove la variabile &lt;code&gt;FS&lt;/code&gt; dal blocco &lt;code&gt;BEGIN{...}&lt;/code&gt; lo script continua a funzionare correttamente?&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Ma basta con awk. Questo articolo non vuole essere una introduzione al linguaggio ma vuole solo mostrare come si può risolvere con AWK il problema che ci sta a cuore. Chi volesse è approfondire la conoscenza del linguaggio può consultare i volumi e le guide online riportate in bibliografia.&lt;/p&gt;&#xA;&lt;h4 id=&#34;rinominare-automaticamente-un-post&#34;&gt;Rinominare automaticamente un post&lt;/h4&gt;&#xA;&lt;p&gt;E finalmente eccoci al programma &lt;code&gt;awk&lt;/code&gt; che rinomina da solo il file Markdown di un post in base al titolo e alla data contenuti nei &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;metadati del documento&lt;/a&gt;, che contengono, fra l&amp;rsquo;altro, il titolo, la data di pubblicazione, la categoria e i tag associati al post stesso.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BEGIN { FS = &amp;#34; &amp;#34;&#xA;        OFS = &amp;#34;-&amp;#34;&#xA;        EXT = &amp;#34;.md&amp;#34;&#xA;      }&#xA;&#xA;$1 ~ /[Dd]ate:/   { date = $2 }&#xA;$1 ~ /[Tt]itle:/  { title = &amp;#34;&amp;#34;&#xA;                    for (i = 2; i &amp;lt;= NF; i++) {&#xA;                        title = title FS tolower($i)&#xA;                    }&#xA;                  }&#xA;&#xA;END { newfilename = date OFS title&#xA;      gsub(&amp;#34;[[:cntrl:]]&amp;#34;, &amp;#34;&amp;#34;, newfilename)&#xA;      gsub(&amp;#34;[\&amp;#34;]+&amp;#34;, &amp;#34;&amp;#34;, newfilename)&#xA;      gsub(&amp;#34;[\.,;:!\?&amp;amp;\$]+&amp;#34;, &amp;#34;&amp;#34;, newfilename)&#xA;      gsub(&amp;#34;[-| ]+&amp;#34;, &amp;#34;-&amp;#34;, newfilename)&#xA;      newfilename = newfilename EXT&#xA;      system(&amp;#34;mv &amp;#34; FILENAME &amp;#34; &amp;#34; newfilename)&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Riassumo brevemente cosa fa il programma, chi non fosse interessato può saltare direttamente al prossimo paragrafo. La prima condizione &lt;code&gt;$1 ~ /[Dd]ate/&lt;/code&gt; cerca la stringa &lt;code&gt;date:&lt;/code&gt; (indifferentemente in minuscolo o maiuscolo) nel primo campo di tutte le righe del post e quando la trova assegna il secondo campo, corrispondente alla data, alla variabile &lt;code&gt;date&lt;/code&gt;.&#xA;La seconda condizione fa lo stesso per il titolo e lo assegna alla variabile &lt;code&gt;title&lt;/code&gt;. Poiché il titolo è distribuito su un numero imprecisato di campi (ricordo che il separatore di campo &lt;code&gt;FS&lt;/code&gt; è lo spazio), viene utilizzato un ciclo &lt;code&gt;for&lt;/code&gt; per leggere ed aggiungere in successione a &lt;code&gt;title&lt;/code&gt; tutti i campi della riga successivi al primo. Il numero di campi presenti nella riga del titolo è contenuto nella variabile di sistema &lt;code&gt;NF&lt;/code&gt;, aggiornata automaticamente dall&amp;rsquo;interprete ogni volta che viene letta una nuova riga.&#xA;La parte finale del programma, racchiusa nel blocco &lt;code&gt;END {...}&lt;/code&gt;, si occupa di definire la variabile &lt;code&gt;newfilename&lt;/code&gt;, contenente il nuovo nome da assegnare al file, e di trasformarla secondo le regole desiderate.&#xA;La variabile &lt;code&gt;newfilename&lt;/code&gt; contiene inizialmente (riga #12) la data e il titolo letti nel post, separati da un trattino (il valore di &lt;code&gt;OFS&lt;/code&gt;). Nelle quattro righe successive viene utilizzata la funzione &lt;code&gt;gsub&lt;/code&gt; per rimuovere da questa variabile tutti i caratteri indesiderati (caratteri di controllo, virgolette, punteggiatura) e per sostituire spazi e trattini (anche multipli) con un trattino singolo. Alla riga #17 viene aggiunta l&amp;rsquo;estensione definita in &lt;code&gt;EXT&lt;/code&gt;, mentre l&amp;rsquo;ultima riga del blocco effettua una chiamata al sistema operativo per rinominare effettivamente il file, utilizzando un&amp;rsquo;altra variabile di sistema, &lt;code&gt;FILENAME&lt;/code&gt;, che contiene il nome originale del file Markdown su cui sta operando lo script.&lt;/p&gt;&#xA;&lt;p&gt;Salviamo il programma nella solita cartella &lt;code&gt;Development&lt;/code&gt; con il nome &lt;code&gt;setpostname.awk&lt;/code&gt;. Per provarlo dobbiamo avere anche un file Markdown contenente nell&amp;rsquo;intestazione (&lt;em&gt;header&lt;/em&gt;) almeno i metadati relativi al titolo e alla data. Possiamo prendere la prima parte di questo post,&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;---&#xA;layout: post  &#xA;title: &amp;#34;Script per tutti i giorni: entra in scena awk&amp;#34;  &#xA;author:&#x9;Sabino Maggi  &#xA;date: 2019-02-18T18:00:00  &#xA;categories:  &#xA;  - programmazione  &#xA;tags:  &#xA;  - awk  &#xA;  - bash  &#xA;  - editor  &#xA;  - gawk  &#xA;  - perl  &#xA;  - script  &#xA;  - terminale  &#xA;comments: true  &#xA;sidebar: true  &#xA;toc: true  &#xA;published: 2019-02-18T18:00:00  &#xA;slug:  &#xA;&#xA;---&#xA;&#xA;Nelle prime tre puntate di questa serie abbiamo imparato a scrivere uno script in `bash` per trasformare una stringa di testo in modo che segua delle  convenzioni ben determinate a priori (qui i link alla [prima](https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/), [seconda](https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/) e [terza](https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/) puntata).&#xA;&#xA;In questo caso particolare,...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;e salvarlo con un nome qualsiasi nella stessa cartella &lt;code&gt;Development&lt;/code&gt;. Poiché la fantasia fa difetto, chiamiamolo &lt;code&gt;articolo.md&lt;/code&gt;. A questo punto lanciamo il Terminale, spostiamoci nella cartella &lt;code&gt;Development&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~/Development&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e lanciamo lo script in &lt;code&gt;awk&lt;/code&gt; con il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$  /usr/bin/awk -f setpostname.awk articolo.md&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e voilà, il file &lt;code&gt;articolo.md&lt;/code&gt; viene rinominato automaticamente in &lt;code&gt;2019-02-18-script-per-tutti-i-giorni-entra-in-scena-awk&lt;/code&gt;, che è esattamente quello che volevamo. Nota per i più curiosi:  dato che &lt;code&gt;awk&lt;/code&gt; ha bisogno di sapere sia il nome dello script contenente i comandi che quello del file da elaborare, si usa l&amp;rsquo;opzione &lt;code&gt;-f&lt;/code&gt; per indicare esplicitamente lo script con i comandi.&lt;/p&gt;&#xA;&lt;p&gt;Perché uso l&amp;rsquo;intero percorso &lt;code&gt;/usr/bin/awk&lt;/code&gt; per richiamare &lt;code&gt;awk&lt;/code&gt;? Semplicemente perché voglio essere sicuro di utilizzare l&amp;rsquo;interprete &lt;code&gt;awk&lt;/code&gt; presente di default in macOS e non la versione estesa installata tramite Homebrew, che funziona in modo leggermente diverso e darebbe degli avvertimenti poco incomprensibili, pur riuscendo lo stesso a rinominare correttamente il file.&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;Ormai siamo quasi a posto con la rinominazione automatica di un post in Markdown (che poi in effetti è solo una scusa per gettare le basi e per poter affrontare script complessi e più utili). Manca solo un piccolissimo dettaglio, che può far diventare questo script del tutto indistinguibile dai comandi standard del sistema operativo e che sarà l&amp;rsquo;argomento della prossima puntata.&lt;/p&gt;&#xA;&lt;h4 id=&#34;bibliografia&#34;&gt;Bibliografia&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Alfred Aho, Brian Kernighan, Peter Weinberger, &lt;a href=&#34;https://archive.org/details/pdfy-MgN0H1joIoDVoIC7&#34;&gt;The AWK programming language&lt;/a&gt;, Addison-Wesley, 1988.&lt;/li&gt;&#xA;&lt;li&gt;Arnold Robbins, &lt;a href=&#34;https://www.gnu.org/software/gawk/manual/&#34;&gt;Gawk: Effective AWK Programming&lt;/a&gt;, Edition 4.2, 2018.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://matt.might.net/articles/sculpting-text/&#34;&gt;Sculpting text with regex, grep, sed, awk, emacs and vim&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Wikibooks, &lt;a href=&#34;https://en.wikibooks.org/wiki/An_Awk_Primer&#34;&gt;An Awk Primer&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Bruce Barnett, &lt;a href=&#34;http://www.grymoire.com/Unix/Awk.html&#34;&gt;Awk a Tutorial and Introduction&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Tutorials Point, &lt;a href=&#34;https://www.tutorialspoint.com/awk/index.htm&#34;&gt;Awk Tutorial&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Una cosa che io trovo bellissima anche dal punto di vista diciamo così, &lt;em&gt;filosofico&lt;/em&gt;, e che mi ricorda i bellissimi articoli di Douglas Hofstadter su Le Scienze sui &lt;a href=&#34;http://www.repubblica.it/2003/g/rubriche/lessicoenuvole/9settemb/9settemb.html&#34;&gt;testi autoreferenziali&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: shell e parametri</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/</link>
      <pubDate>Sun, 30 Dec 2018 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm9.staticflickr.com/8002/7151170579_753c6fb9c0.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; Foto: &lt;a href=&#34;https://www.flickr.com/photos/osr/&#34;&gt;Trammell Hudson&lt;/a&gt; su Flickr.&lt;/p&gt;&#xA;&lt;p&gt;Lo script di conversione del titolo di un post mostrato alla fine della &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;puntata precedente&lt;/a&gt; è diventato ormai quasi &amp;ldquo;utilizzabile&amp;rdquo;. Mancano solo un paio di tocchi finali, che vedremo nel corso di questa terza parte.&lt;/p&gt;&#xA;&lt;h4 id=&#34;una-casa-per-i-programmi&#34;&gt;Una casa per i programmi&lt;/h4&gt;&#xA;&lt;p&gt;Prima di proseguire è bene decidere una volta per tutte dove salvare gli script che stiamo sviluppando. Non so voi, ma io preferisco usare una cartella dedicata allo scopo invece di buttare tutto dove capita. In tutti gli articoli di questa serie gli script in fase di sviluppo saranno salvati nella cartella &lt;code&gt;Development&lt;/code&gt;, situata all&amp;rsquo;interno della cartella &lt;code&gt;Home&lt;/code&gt; (o &lt;code&gt;Inizio&lt;/code&gt;) dell’utente che ha effettuato il login (la cartella &lt;code&gt;Home&lt;/code&gt; è quella rappresentata dall’icona di una casetta). Ovviamente siete liberi di usare un altro nome e un&amp;rsquo;altra posizione sul disco rigido, ma dovrete ricordarvi di modificare di conseguenza i percorsi dei comandi.&lt;/p&gt;&#xA;&lt;p&gt;Già che ci siamo, creiamo subito la cartella &lt;code&gt;Development&lt;/code&gt;. Se usate il Finder non ho bisogno di dirvi come si fa, se invece usate il Terminale basta eseguire i comandi&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~&#xA;$ mkdir Development&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove il primo comando, &lt;code&gt;cd ~&lt;/code&gt; (ma su macOS e varie versioni di Linux è sufficiente il semplice &lt;code&gt;cd&lt;/code&gt;) ci fa spostare nella nostra &lt;code&gt;Home&lt;/code&gt;, mentre il secondo comando crea la nuova directory &lt;code&gt;Development&lt;/code&gt;. Nelle shell Unix come &lt;code&gt;bash&lt;/code&gt;, il simbolo tilde &lt;code&gt;~&lt;/code&gt; (che si scrive premendo ALT-5) indica la &lt;code&gt;Home&lt;/code&gt; dell&amp;rsquo;utente.&lt;/p&gt;&#xA;&lt;p&gt;Volendo potremmo anche eseguire semplicemente&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ mkdir ~/Development&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;che crea la directory desiderata con un unico comando.&lt;/p&gt;&#xA;&lt;p&gt;Qualche breve nota generale. In questo contesto i termini &lt;em&gt;script&lt;/em&gt; o &lt;em&gt;programma&lt;/em&gt; sono equivalenti e li userò indifferentemente. Lo stesso vale per &lt;em&gt;directory&lt;/em&gt; e &lt;em&gt;cartella&lt;/em&gt;. Io preferisco il primo, ma so benissimo che, da quando esistono le interfacce grafiche, il termine &amp;ldquo;cartella&amp;rdquo; è diventato di uso molto più comune. Nel seguito cercherò di usare &amp;ldquo;cartella&amp;rdquo; nel testo discorsivo degli articoli e &amp;ldquo;directory&amp;rdquo; quando si tratterà di riferirsi ai comandi di &lt;code&gt;bash&lt;/code&gt; e al Terminale. Infine, il simbolo &lt;code&gt;$&lt;/code&gt; prima di ogni comando è il cosiddetto &lt;code&gt;prompt&lt;/code&gt; e serve ad indicare che stiamo interagendo con il Terminale; non fa parte dei comandi e quindi non deve mai essere inserito quando scriviamo un comando nel Terminale.&lt;/p&gt;&#xA;&lt;h4 id=&#34;andare-con-le-proprie-gambe&#34;&gt;Andare con le proprie gambe&lt;/h4&gt;&#xA;&lt;p&gt;Nella &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;puntata precedente&lt;/a&gt; siamo arrivati ad usare uno dei tanti &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;editor di testo&lt;/a&gt; disponibili su macOS per inserire queste righe di codice&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;string=&amp;#34;La privacy al tempo dell&amp;#39;Internet of Things: gran finale&amp;#34;&#xA; &#xA;fix_string=$(echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/&amp;#39;/ /g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/[[:punct:]]//g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/ /-/g&amp;#34;)&#xA; &#xA;converted_string=$fix_string&#xA;echo $converted_string&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ora possiamo salvare lo script nella cartella &lt;code&gt;~/Development/&lt;/code&gt;, dandogli un nome significativo che ci aiuti a ricordare anche in un secondo momento cosa fa il programma. Molto meglio quindi usare un nome come &lt;code&gt;convert_title.sh&lt;/code&gt; piuttosto che un criptico &lt;code&gt;SCCUSIFJ.sh&lt;/code&gt;, anche se profuma tanto di DOS e di anni &amp;lsquo;80.&lt;/p&gt;&#xA;&lt;p&gt;Nei sistemi Unix come macOS l&amp;rsquo;estensione &lt;code&gt;.sh&lt;/code&gt; non è indispensabile ma ci aiuta a capire al volo che il file è uno script della shell (da cui &lt;code&gt;.sh&lt;/code&gt;). È possibile usare altre estensioni come &lt;code&gt;.shell&lt;/code&gt;, &lt;code&gt;.script&lt;/code&gt;, &lt;code&gt;.cmd&lt;/code&gt; o perfino &lt;code&gt;.bat&lt;/code&gt;, per il sistema operativo non cambia nulla.&lt;/p&gt;&#xA;&lt;p&gt;A questo punto possiamo finalmente di eseguire lo script. Lanciamo il Terminale, spostiamoci nella cartella dove abbiamo salvato lo script&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~/Development&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ed eseguiamo lo script con il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ sh convert_title.sh&#xA;la-privacy-al-tempo-dell-internet-of-things-gran-finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ottenendo, come previsto, la trasformazione della stringa definita nella &lt;code&gt;string&lt;/code&gt; nel &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;formato adatto&lt;/a&gt; a Jekyll o a Wordpress.&lt;/p&gt;&#xA;&lt;p&gt;Per eseguire lo script dobbiamo premettere al nome del file il comando &lt;code&gt;sh&lt;/code&gt; che indica al sistema operativo che il file in questione contiene una serie di &lt;a href=&#34;https://melabit.wordpress.com/2014/11/06/script-di-shell-in-os-x/&#34;&gt;comandi di shell&lt;/a&gt;, cioè di comandi che permettono di interagire con il sistema operativo stesso (attenzione, il &lt;em&gt;comando&lt;/em&gt; &lt;code&gt;sh&lt;/code&gt; è una cosa ben diversa dall&amp;rsquo;&lt;em&gt;estensione&lt;/em&gt; &lt;code&gt;.sh&lt;/code&gt; vista prima!). Con questa informazione, il sistema operativo trasferisce l&amp;rsquo;esecuzione dello script alla shell di default, che in macOS e nella maggior parte dei sistemi Linux attuali è &lt;code&gt;bash&lt;/code&gt;. Niente però impedisce di &lt;em&gt;forzare&lt;/em&gt; l&amp;rsquo;utilizzo di &lt;code&gt;bash&lt;/code&gt;, scrivendo esplicitamente&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ bash convert_title.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;al posto di &lt;code&gt;sh convert_title.sh&lt;/code&gt;, oppure di utilizzare &lt;a href=&#34;https://opensource.com/business/16/3/top-linux-shells&#34;&gt;altre shell&lt;/a&gt; eventualmente disponibili nel sistema, come &lt;code&gt;tcsh&lt;/code&gt;, &lt;code&gt;ksh&lt;/code&gt;, &lt;code&gt;zsh&lt;/code&gt; o &lt;code&gt;fish&lt;/code&gt; (argomento che non verrà trattato in questa serie).&lt;/p&gt;&#xA;&lt;p&gt;Purtroppo affidarsi alla configurazione di default del sistema può creare problemi, ad esempio perché qualcuno ha cambiato la shell di default, magari solo per fare una prova, dimenticando di ripristinare la configurazione iniziale. Per fortuna in genere queste cose non succedono per cui possiamo stare relativamente tranquilli. Però il meccanismo appena descritto non è né semplice, né tanto meno a prova di bomba.&lt;/p&gt;&#xA;&lt;p&gt;Proviamo a semplificarci la vita con due piccole modifiche. Prima di tutto utilizziamo il comando &lt;code&gt;chmod&lt;/code&gt; per rendere &lt;em&gt;eseguibile&lt;/em&gt; lo script all’utente attuale del Mac&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u+x convert_title.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove la &lt;code&gt;u&lt;/code&gt; indica l&amp;rsquo;utente che sta usando il Mac e il simbolo &lt;code&gt;+x&lt;/code&gt; significa che il file viene reso eseguibile (la &lt;code&gt;x&lt;/code&gt; sta per &lt;em&gt;eXecute&lt;/em&gt;). Se volessimo rimuovere questa autorizzazione, non dovremmo far altro che eseguire il comando duale&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u-x convert_title.sh`&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Se invece volessimo autorizzare tutti gli utenti del Mac ad eseguire questo script, dovremmo scrivere&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod a+x convert_title.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;mentre per autorizzare solo gli utenti che fanno parte del nostro stesso gruppo di lavoro oppure tutti gli altri utenti fuori dal nostro gruppo di lavoro, dobbiamo usare rispettivamente &lt;code&gt;chmod g+x convert_title.sh&lt;/code&gt; oppure &lt;code&gt;chmod o+x convert_title.sh&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Ma queste sono finezze utili per i server a cui accedono decine e decine di utenti contemporaneamente, i Mac sono sostanzialmente macchine monoutente (o che gestiscono un numero molto ridotto di utenti), per cui &lt;code&gt;chmod u+x&lt;/code&gt; (o al massimo &lt;code&gt;chmod a+x&lt;/code&gt;) a noi basta e avanza.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;altra modifica utile è quella di indicare esplicitamente al sistema operativo quale shell vogliamo utilizzare per interpretare i comandi contenuti nel nostro script. Per farlo è sufficiente aggiungere all&amp;rsquo;inizio dello dello script la sequenza di caratteri &lt;code&gt;#!&lt;/code&gt;, il cosiddetto &lt;a href=&#34;https://en.wikipedia.org/wiki/Shebang_%28Unix%29&#34;&gt;shebang&lt;/a&gt;,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; seguita dal percorso completo al programma di shell che vogliamo usare.&lt;/p&gt;&#xA;&lt;!--&#xA;(per motivi che saranno chiari fra poco, è meglio inserire lo shebang e il percorso esattamente nella _prima_ riga dello script).&#xA;--&gt;&#xA;&lt;p&gt;Dato che qui usiamo &lt;code&gt;bash&lt;/code&gt;, il nostro script diventa&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash&#xA;&#xA;string=&amp;#34;La privacy al tempo dell&amp;#39;Internet of Things: gran finale&amp;#34;&#xA; &#xA;fix_string=$(echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/&amp;#39;/ /g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/[[:punct:]]//g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/ /-/g&amp;#34;)&#xA; &#xA;converted_string=$fix_string&#xA;echo $converted_string&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ma come lo troviamo il percorso di &lt;code&gt;bash&lt;/code&gt;? C&amp;rsquo;è un comando anche per questo: &lt;code&gt;which&lt;/code&gt; seguito dal nome di un qualunque comando Unix restituisce proprio il percorso completo del comando all&amp;rsquo;interno del filesystem. Di conseguenza &lt;code&gt;which bash&lt;/code&gt; restituisce&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ which bash&#xA;/bin/bash&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;che è proprio ciò che dobbiamo inserire in testa allo script subito dopo lo shebang.&lt;/p&gt;&#xA;&lt;!--&#xA;Se la stringa `#!/bin/bash` è esattamente la prima riga dello script, al momento del salvataggio lo script diventa automaticamente eseguibile da tutti gli utenti del sistema, proprio come se avessimo usato il comando `chmod a+x convert_title.sh` descritto prima. Dal punto di vista della sicurezza non è il massimo, ma per i nostri piccoli script inoffensivi può andar bene così.&#xA;--&gt;&#xA;&lt;p&gt;Per verificarlo, basta provare a salvare lo script modificato con un nome diverso, diciamo &lt;code&gt;convert_title_v2.sh&lt;/code&gt; e rendiamolo esegubile con il comando &lt;code&gt;chmod a+x convert_title_v2.sh&lt;/code&gt; descritto prima.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; A differenza di &lt;code&gt;convert_title.sh&lt;/code&gt;, questo secondo script potrà essere eseguito senza dover premettere &lt;code&gt;sh&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ./convert_title_v2.sh &#xA;la-privacy-al-tempo-dell-internet-of-things-gran-finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Per una serie di ragioni che vedremo in una prossima puntata, dobbiamo però &lt;em&gt;aiutare&lt;/em&gt; il sistema operativo a trovare lo script aggiungendo esplicitamente il percorso allo script da eseguire. Poiché nei sistemi Unix (e non solo), il punto &lt;code&gt;.&lt;/code&gt; indica la cartella corrente (mentre il doppio punto &lt;code&gt;..&lt;/code&gt; si riferisce alla cartella che contiene la cartella corrente), scrivere &lt;code&gt;./&lt;/code&gt; immediatamente prima del nome dello script equivale a dire al sistema operativo che lo script si trova nella cartella corrente, che in questo caso è la cartella dove siamo &lt;em&gt;entrati&lt;/em&gt; all&amp;rsquo;inizio di questa puntata con il comando &lt;code&gt;cd ~/Development&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h4 id=&#34;parametri-sulla-linea-di-comando&#34;&gt;Parametri sulla linea di comando&lt;/h4&gt;&#xA;&lt;p&gt;C&amp;rsquo;è ancora una cosa che non va bene. Ogni volta che vogliamo cambiare la stringa da convertire dobbiamo intervenire direttamente sullo script, modificando la variabile &lt;code&gt;string&lt;/code&gt;. Facendo così è facile sbagliare, e in ogni caso sarebbe molto più comodo rendere lo script indipendente dai dati sui quali deve operare (in questo caso la stringa da convertire).&lt;/p&gt;&#xA;&lt;p&gt;Non voglio entrare nei dettagli (ma ci sarà tempo per approfondire la questione), per ora basterà dire che per rendere lo script indipendente dalla stringa da trasformare è sufficiente assegnare a &lt;code&gt;string&lt;/code&gt; il valore della variabile convenzionale &lt;code&gt;$1&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash&#xA;&#xA;string=$1&#xA;&#xA;fix_string=$(echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/&amp;#39;/ /g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/[[:punct:]]//g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/ /-/g&amp;#34;)&#xA; &#xA;converted_string=$fix_string&#xA;echo $converted_string&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;L&amp;rsquo;interprete &lt;code&gt;bash&lt;/code&gt; assegna automaticamente alle variabili &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt;, &amp;hellip; &lt;code&gt;$9&lt;/code&gt;, dette &lt;em&gt;parametri posizionali&lt;/em&gt;, i valori degli &lt;em&gt;argomenti&lt;/em&gt; dello script, cioè i valori dei parametri presenti sulla linea di comando subito dopo il nome dello script da eseguire.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; I diversi parametri sono separati da uno o più spazi, e se un parametro contiene degli spazi bisogna racchiuderlo fra virgolette, non importa se semplici &lt;code&gt;&#39;&lt;/code&gt; o doppie &lt;code&gt;&amp;quot;&lt;/code&gt; (però è preferibile &lt;del&gt;essere consistenti ed&lt;/del&gt; evitare di mescolare i due simboli).&lt;/p&gt;&#xA;&lt;p&gt;Salviamo lo script così modificato con il solito nome &lt;code&gt;convert_title.sh&lt;/code&gt; e torniamo al Terminale. Ora per usare lo script dobbiamo scrivere la stringa da convertire direttamente sulla linea di comando, subito dopo il nome del file, racchiudendola fra virgolette dato che la stringa contiene degli spazi (io preferisco usare le virgolette doppie)&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ./convert_title.sh &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot;&#xA;la-privacy-al-tempo-dell-internet-of-things-gran-finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Naturalmente niente impedisce di trasformare stringhe molto più lunghe, come ad esempio un paragrafo di questo stesso articolo, l&amp;rsquo;unica limitazione è che la stringa non deve contenere dei caratteri di &lt;a href=&#34;https://it.wikipedia.org/wiki/Ritorno_a_capo&#34;&gt;&lt;em&gt;ritorno a capo&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ convert_title.sh &amp;quot;Purtroppo affidarsi alla configurazione di default del sistema può creare problemi, ad esempio perché qualcuno ha cambiato la shell di default, magari solo per fare una prova, dimenticando di ripristinare la configurazione iniziale. Per fortuna in genere queste cose non succedono per cui possiamo stare relativamente tranquilli. Però il meccanismo appena descritto non è né semplice, né tanto meno a prova di bomba.&amp;quot;&#xA;purtroppo-affidarsi-alla-configurazione-di-default-del-sistema-può-creare-problemi-ad-esempio-perché-qualcuno-ha-cambiato-la-shell-di-default-magari-solo-per-fare-una-prova-dimenticando-di-ripristinare-la-configurazione-iniziale-per-fortuna-in-genere-queste-cose-non-succedono-per-cui-possiamo-stare-relativamente-tranquilli-però-il-meccanismo-appena-descritto-non-è-né-semplice-né-tanto-meno-a-prova-di-bomba&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Se guardiamo attentamente il risultato della conversione notiamo come lo script non riesce a trattare correttamente i caratteri accentati, come era stato già notato esplicitamente nella &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;prima puntata&lt;/a&gt; di questa serie di articoli. Per ora sarà sufficiente evitare di usare i caratteri accentati o almeno scriverli con una vocale seguita da un apostrofo, come se stessimo usando una tastiera americana.&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni-per-ora&#34;&gt;Conclusioni (per ora)&lt;/h4&gt;&#xA;&lt;p&gt;Se togliessimo l&amp;rsquo;estensione al nome del file, lo script &lt;code&gt;convert_title&lt;/code&gt; diventerebbe quasi indistinguibile dai comandi veri e propri del sistema operativo. Dico &amp;ldquo;quasi&amp;rdquo; perché per poterlo eseguire dobbiamo ancora premettere il percorso alla cartella corrente al nome del file. Ci sarà modo per risolvere questo (piccolo) problema, i più impazienti possono &lt;a href=&#34;https://melabit.wordpress.com/2014/11/06/script-di-shell-in-os-x/&#34;&gt;leggere qui&lt;/a&gt; per capire in anteprima come si fa.&lt;/p&gt;&#xA;&lt;p&gt;La prossima volta faremo un veloce ripasso dei comandi presentati in queste prime tre puntate, utile per consolidare quanto visto finora prima di passare ad usare uno degli strumenti più potenti ma anche meno conosciuti dell&amp;rsquo;arsenale Unix.&lt;/p&gt;&#xA;&lt;h5 id=&#34;revisioni&#34;&gt;Revisioni&lt;/h5&gt;&#xA;&lt;p&gt;&lt;strong&gt;30-12-2018&lt;/strong&gt;: Corretta una imprecisione relativa al cambiamento dei permessi dei file quando la prima riga di uno script contiene lo shebang e il percorso all&amp;rsquo;interprete &lt;code&gt;bash&lt;/code&gt; (si veda la nota 2).&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Detto anche &lt;em&gt;sha-bang&lt;/em&gt; o &lt;em&gt;hashbang&lt;/em&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Se la stringa &lt;code&gt;#!/bin/bash&lt;/code&gt; è esattamente la prima riga dello script, quando salviamo lo script l&amp;rsquo;editor TextMate lo rende eseguibile da tutti gli utenti del sistema, proprio come se avessimo usato esplicitamente il comando &lt;code&gt;chmod a+x ...&lt;/code&gt;. È una particolarità del solo TextMate, tutti gli altri editor che ho provato (Atom, BBEdit, Visual Studio Code e CotEditor fra quelli grafici, nano, emacs e vim per quanto riguarda gli editor testuali) non modificano mai i permessi del file.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Se abbiamo bisogno di più di nove parametri, dobbiamo racchiudere quelli dal decimo in poi fra parentesi graffe, scrivendo &lt;code&gt;${10}&lt;/code&gt;, &lt;code&gt;${11}&lt;/code&gt; e così via.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>E sono cinque!</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/12/18/e-sono-cinque/</link>
      <pubDate>Tue, 18 Dec 2018 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/12/18/e-sono-cinque/</guid>
      <description>&lt;img src=&#34;https://melabit.files.wordpress.com/2018/12/wordcloud_2018.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Oggi il blog compie cinque anni. Purtroppo me ne sono ricordato solo all&amp;rsquo;ultimo momento e non ho avuto il tempo di fare una analisi dettagliata come mi ero ripromesso di fare. Pazienza, magari ci sarà occasione in una circostanza meno &amp;ldquo;tonda&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Una cosa che mi colpisce sempre è che, nonostante il blog sia in italiano, ben il 10% degli accessi provenga da fuori Italia. Chissà cosa riescono a capire i poveri visitatori che leggono gli articoli tramite Google Traduttore!&lt;/p&gt;&#xA;&lt;p&gt;Un&amp;rsquo;altra cosa che mi colpisce è che, oltre ai tanti lettori affezionati che non mi stancherò mai di ringraziare per la loro immensa pazienza, circa due terzi dei vsitatori arrivano al blog tramite i motori di ricerca. Anzi, tramite Google, gli altri motori di ricerca, anche Bing o DuckDuckGo (e mi dispiace soprattutto per quest&amp;rsquo;ultimo), praticamente non esistono. Il che significa da un lato che il blog si posiziona abbastanza bene nelle ricerche sul web (anche se io non faccio nulla per spingere in su la &lt;a href=&#34;https://sos-wp.it/ottimizzare-la-seo-del-tuo-blog/&#34;&gt;SEO&lt;/a&gt; del blog), dall&amp;rsquo;altro che gli articoli hanno una vita piuttosto lunga e vengono cercati e letti anche molti anni dopo la pubblicazione. L&amp;rsquo;articolo più letto in assoluto quest&amp;rsquo;anno, &lt;a href=&#34;https://melabit.wordpress.com/2016/03/11/usare-un-mac-con-powerpc-oggi/&#34;&gt;Usare un Mac con PowerPC oggi&lt;/a&gt; è del 2016 e ha un numero di letture che tende a crescere ogni mese. Lo stesso sta succedendo all&amp;rsquo;articolo più letto pubblicato nel 2018, &lt;a href=&#34;https://melabit.wordpress.com/2018/06/25/ma-il-fusion-drive-serve-ancora/&#34;&gt;Ma il Fusion Drive serve ancora?&lt;/a&gt;, che ogni mese ha più che raddoppiato il numero di letture rispetto al mese precedente.&lt;/p&gt;&#xA;&lt;p&gt;Fra le cose che &lt;em&gt;non&lt;/em&gt; mi piacciono c&amp;rsquo;è quella di aver diminuito fortemente la cadenza di pubblicazione dei nuovi articoli, passando dai due articoli a settimana del 2014 a un solo articolo ogni dieci giorni di quest&amp;rsquo;anno. Sono valori medi, ma riflettono bene la scarsa velocità con la quale riesco a pubblicare nuovo materiale. Non che mi manchino gli spunti e le idee, anzi, quello che mi manca è il tempo per scrivere in pace e poi per rivedere quello che scrivo. In compenso la lunghezza media di ciascun articolo è cresciuta significativamente nel tempo, anche se non so se questa sia una cosa positiva o no.&lt;/p&gt;&#xA;&lt;p&gt;Altra cosa che &lt;em&gt;non&lt;/em&gt; mi piace è il numero di commenti, che si è ridotto anch&amp;rsquo;esso in modo molto significativo. Dal picco di circa 550 commenti del 2015 si è scesi ad appena 159 nel 2018, nonostante nello stesso periodo di tempo il numero di visitatori sia quasi raddoppiato. Mi piacerebbe che ci fosse maggiore interazione con chi legge il blog, e vorrei anche sapere se posso fare qualcosa per favorire questa interazione.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://automatetheboringstuff.com/&#34;&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2018/12/automate_cover.png&#34; alt=&#34;Copertina di Automate the Boring Stuff with Python&#34; class=&#34;aligncenter&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Prima di concludere, un piccolo consiglio di lettura. Ho scoperto da poco il libro &lt;a href=&#34;https://automatetheboringstuff.com/&#34;&gt;Automate the Boring Stuff with Python&lt;/a&gt;, che si può leggere gratuitamente sul web o comprare in edizione elettronica o cartacea sul sito della &lt;a href=&#34;https://nostarch.com/automatestuff&#34;&gt;casa editrice&lt;/a&gt; o sul solito &lt;a href=&#34;https://www.amazon.it/Automate-Boring-Stuff-Python-Programming/dp/1593275994&#34;&gt;Amazon&lt;/a&gt;. È una vera bomba, ed è pure perfettamente in tema con la &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;serie dedicata al Terminale e allo &lt;em&gt;scripting&lt;/em&gt;&lt;/a&gt; di questo periodo. Consigliatissimo!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: dalla linea di comando al programma</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/</link>
      <pubDate>Wed, 05 Dec 2018 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm4.staticflickr.com/3701/9171586772_b1ec32a77f_b.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; Foto: &lt;a href=&#34;https://www.flickr.com/photos/mratzloff/&#34;&gt;Matthew Ratzloff&lt;/a&gt; su Flickr.&lt;/p&gt;&#xA;&lt;p&gt;Il comando per generare automaticamente il nome del file nel formato previsto da Jekyll (o da Wordpress) dal titolo del post presentato alla fine della &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;prima puntata&lt;/a&gt; potrà anche essere interessante dal punto di vista didattico ma, diciamolo, è poco pratico per essere utilizzato &lt;em&gt;veramente&lt;/em&gt;. Bisogna lanciare il Terminale, andare a cercare il comando da qualche parte, copiarlo e incollarlo nel Terminale, cancellare il titolo preesistente e incollare il titolo del nuovo post su cui stiamo lavorando&amp;hellip; Si fa prima a fare tutto a mano nel Finder!&lt;/p&gt;&#xA;&lt;p&gt;Ma se lo trasformiamo in uno &lt;em&gt;script&lt;/em&gt;, cioè in un piccolo programma eseguibile direttamente dal Terminale come un qualunque comando del sistema operativo, le cose diventano improvvisamente molto più interessanti.&lt;/p&gt;&#xA;&lt;h4 id=&#34;dove-vai-se-leditor-non-ce-lhai&#34;&gt;Dove vai se l&amp;rsquo;editor non ce l&amp;rsquo;hai?&lt;/h4&gt;&#xA;&lt;p&gt;Per lavorare sugli script è fondamentale avere a disposizione un buon editor di testo. In macOS sono già integrati due pesi massimi, &lt;code&gt;emacs&lt;/code&gt; e &lt;code&gt;vi&lt;/code&gt;, eseguibili direttamente dal Terminale tramite i comandi omonimi. Fatevi un favore e non usateli.&lt;/p&gt;&#xA;&lt;p&gt;Questi due editor, che hanno dato origine ad una vera e propria guerra di religione fra i fan dell&amp;rsquo;uno e dell&amp;rsquo;altro programma, sono perfetti per i professionisti, per chi è già esperto di programmazione ed è disposto ad affrontare una fase di apprendimento lunga e piuttosto impervia. Ma per chi è all&amp;rsquo;inizio e deve concentrarsi sull&amp;rsquo;imparare le basi e la logica della programmazione, un editor troppo complicato è più che altro un ostacolo ed una distrazione.&lt;/p&gt;&#xA;&lt;p&gt;Molto meglio installare uno dei tanti editor grafici disponibili per macOS. Fra &lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt;, &lt;a href=&#34;http://www.barebones.com/products/bbedit/&#34;&gt;BBEdit&lt;/a&gt;, &lt;a href=&#34;https://macromates.com/&#34;&gt;TextMate&lt;/a&gt;, &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt;, c&amp;rsquo;è solo l&amp;rsquo;imbarazzo della scelta. Sono tutti gratuiti (si, ora anche BBEdit è gratuito, la licenza serve per sbloccare le funzioni avanzate utili per i professionisti), sono tutti di ottima qualità (si, anche un prodotto Microsoft come Visual Studio Code può essere ottimo). Io preferisco usare TextMate e Atom &amp;ndash; di quest&amp;rsquo;ultimo mi piace moltissimo la possibilità di sincronizzare automaticamente le impostazioni, i plugin e i temi fra tutti i computer su cui l&amp;rsquo;ho installato, che siano Mac o generici PC con Linux o Windows &amp;ndash; però BBEdit è perfetto per i file di grosse (o meglio dire enormi) dimensioni come quelli che mi stanno capitando per le mani ultimamente. Mentre Visual Studio Code&amp;hellip; beh, Visual Studio Code è stato una vera sorpresa sin dalla prima volta che l&amp;rsquo;ho usato.&lt;/p&gt;&#xA;&lt;h4 id=&#34;dalla-linea-di-comando-allo-script&#34;&gt;Dalla linea di comando allo script&lt;/h4&gt;&#xA;&lt;p&gt;Lanciamo quindi l&amp;rsquo;editor che preferiamo e incolliamo l&amp;rsquo;ultima versione del comando di Terminale visto nella &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;puntata precedente&lt;/a&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | tr &amp;quot;[:upper:]&amp;quot; &amp;quot;[:lower:]&amp;quot; | sed &amp;quot;s/&#39;/ /g&amp;quot; | sed &amp;quot;s/[[:punct:]]//g&amp;quot; | sed &amp;quot;s/ /-/g&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;In questo comando c&amp;rsquo;è una parte variabile, la stringa &amp;ldquo;La privacy al tempo dell&amp;rsquo;Internet of Things: gran finale&amp;rdquo;, che dobbiamo cambiare ogni volta che vogliamo generare un nuovo titolo, mentre tutto il resto rimane sempre inalterato (a meno di non modificare di proposito il codice).&lt;/p&gt;&#xA;&lt;p&gt;È sempre consigliabile separare le parti variabili del codice da quelle che rimangono sempre uguali, per evitare di alterare il programma per errore e renderlo inusabile. In questo caso, basta definire una &lt;em&gt;variabile&lt;/em&gt; a cui viene assegnata la stringa da elaborare, usata come una specie di segnaposto nel resto del programma, e separare anche visivamente con una o più righe vuote le variabili dal resto del programma. Lo script diventa così&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;string=&amp;#34;La privacy al tempo dell&amp;#39;Internet of Things: gran finale&amp;#34;&#xA;&#xA;echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34; | sed &amp;#34;s/&amp;#39;/ /g&amp;#34; | sed &amp;#34;s/[[:punct:]]//g&amp;#34; | sed &amp;#34;s/ /-/g&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;dove la prima riga definisce la variabile &lt;code&gt;string&lt;/code&gt;, che viene poi usata nel comando vero e proprio.&lt;/p&gt;&#xA;&lt;p&gt;Da notare che quando si assegna una variabile in &lt;code&gt;bash&lt;/code&gt; non si possono mettere degli spazi prima e dopo l&amp;rsquo;operatore di assegnazione &lt;code&gt;=&lt;/code&gt;. In altre parole il nome della variabile, l&amp;rsquo;operatore e il valore della variabile devono essere scritti &lt;em&gt;tutti attaccati&lt;/em&gt;. Inoltre, quando si usa la variabile nello script bisogna sempre anteporre il prefisso &lt;code&gt;$&lt;/code&gt; e scriverla come &lt;code&gt;$string&lt;/code&gt;. Sono due particolarità di &lt;code&gt;bash&lt;/code&gt; di cui è facile dimenticarsi quando si è abituati ad usare altri linguaggi di programmazione, a me succede anche troppo spesso.&lt;/p&gt;&#xA;&lt;p&gt;Guardiamo ora la seconda riga. Nel comando originale da Terminale l&amp;rsquo;abbiamo scritta tutta di seguito, usando l&amp;rsquo;operatore &lt;code&gt;|&lt;/code&gt; per trasferire il risultato di un comando al comando immediatamente successivo, che lo usa come dato di ingresso da elaborare. È una pratica che evita la creazione di troppe variabili, magari usate solo una volta, che è diventata popolare di recente in &lt;a href=&#34;https://www.r-project.org/&#34;&gt;R&lt;/a&gt;, un linguaggio di programmazione specializzato nell&amp;rsquo;analisi statistica dei dati.&lt;/p&gt;&#xA;&lt;p&gt;Personalmente la trovo una pratica poco lungimirante. Sarà anche comoda nel momento in cui sviluppiamo un programma, ma rende molto più difficile capire in un secondo momento quello che fa lo script. Ormai la memoria dei computer è gigantesca, possiamo benissimo sprecarne un po&amp;rsquo; per definire qualche variabile in più.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Una versione riveduta del programma precedente, nella quale i risultati di ciascuna fase di elaborazione vengono salvati in una variabile diversa, può quindi essere&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;string=&amp;#34;La privacy al tempo dell&amp;#39;Internet of Things: gran finale&amp;#34;&#xA;&#xA;lowercase=$(echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34;)&#xA;del_apostr=$(echo $lowercase | sed &amp;#34;s/&amp;#39;/ /g&amp;#34;)&#xA;del_punct=$(echo $del_apostr | sed &amp;#34;s/[[:punct:]]//g&amp;#34;)&#xA;fix_spaces=$(echo $del_punct | sed &amp;#34;s/ /-/g&amp;#34;)&#xA;&#xA;converted_string=$fix_spaces&#xA;echo $converted_string&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Qui devo ammettere di avere esagerato. Se la prima versione scritta tutta d&amp;rsquo;un fiato era difficile da leggere e da capire, usare una variabile diversa per ogni passo del programma è altrettanto estremo. Un buon compromesso potrebbe essere&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;string=&amp;#34;La privacy al tempo dell&amp;#39;Internet of Things: gran finale&amp;#34;&#xA;&#xA;fix_string=$(echo $string | tr &amp;#34;[:upper:]&amp;#34; &amp;#34;[:lower:]&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/&amp;#39;/ /g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/[[:punct:]]//g&amp;#34;)&#xA;fix_string=$(echo $fix_string | sed &amp;#34;s/ /-/g&amp;#34;)&#xA;&#xA;converted_string=$fix_string&#xA;echo $converted_string&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;in cui si usa una variabile (&lt;code&gt;string&lt;/code&gt;) per la stringa da elaborare, un&amp;rsquo;altra (&lt;code&gt;fix_string&lt;/code&gt;) per conservare i risultati intermedi ed infine un&amp;rsquo;ultima variabile (&lt;code&gt;converted_string&lt;/code&gt;) per il risultato finale del programma.&lt;/p&gt;&#xA;&lt;p&gt;Se si guardano attentamente le due ultime versioni dello script, si nota che ho continuato ad usare l&amp;rsquo;operatore &lt;code&gt;|&lt;/code&gt; per inviare a &lt;code&gt;sed&lt;/code&gt; o a &lt;code&gt;tr&lt;/code&gt; la stringa da elaborare. Non è una contraddizione rispetto a quanto dicevo prima. Una cosa è scrivere una sequenza di quattro, cinque o più comandi collegati uno all&amp;rsquo;altro a formare una catena di montaggio inestricabile, un&amp;rsquo;altra è utilizzare ripetutamente una struttura ben definita e riconoscibile come &lt;code&gt;echo $... | tr &amp;quot;...&amp;quot;&lt;/code&gt; oppure &lt;code&gt;echo $... | sed &amp;quot;...&amp;quot;&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Del resto non ci sono alternative: sia &lt;code&gt;sed&lt;/code&gt; che &lt;code&gt;tr&lt;/code&gt; sono fatti per operare su un file oppure in modo interattivo nel Terminale (si scrive una stringa nel Terminale, si preme Invio e &lt;code&gt;sed&lt;/code&gt; o &lt;code&gt;tr&lt;/code&gt; la elaborano, stampano il risultato e si mettono in attesa di una nuova stringa finché non li interrompiamo premendo CTRL-D) e l&amp;rsquo;unico modo per &lt;em&gt;obbligarli&lt;/em&gt; a lavorare da programma e usare &lt;code&gt;echo&lt;/code&gt; per fornirgli il dato in ingresso già bello e pronto.&lt;/p&gt;&#xA;&lt;p&gt;Al nostro script mancano ancora due cosette per essere &lt;em&gt;quasi&lt;/em&gt; comodo da usare, ma questo sarà l&amp;rsquo;argomento della prossima puntata.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;A meno naturalmente di non avere dei grossi limiti di memoria, come succede quando si scrivono programmi per dispositivi &lt;em&gt;embedded&lt;/em&gt; o dell&amp;rsquo;IoT, oppure di dover scrivere del codice molto efficiente per applicazioni ultrasofisticate. Ma chi è alle prese con questi problemi non ha bisogno di leggere questi articoli.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: semplici modifiche alle stringhe di testo</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/</link>
      <pubDate>Fri, 23 Nov 2018 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm3.staticflickr.com/2472/3797070188_ece79b25b3_b.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; Foto: &lt;a href=&#34;https://www.flickr.com/photos/telwink/&#34;&gt;telwink&lt;/a&gt; su Flickr.&lt;/p&gt;&#xA;&lt;p&gt;Succede più spesso di quanto mi renda conto. Devo rinominare dei file, modificare un testo o fare altri pasticci con i miei documenti. Potrei usare una delle tante applicazioni &lt;em&gt;ad hoc&lt;/em&gt; fatte per fare &lt;em&gt;proprio quello&lt;/em&gt;. Ma perché perdere tempo ad installare ed imparare ad usare l&amp;rsquo;ennesima applicazione se con il Terminale posso fare prima (e meglio)?&lt;/p&gt;&#xA;&lt;p&gt;Basta qualche comando ben piazzato nel Terminale, a volte qualche piccolo script in &lt;code&gt;bash&lt;/code&gt; o in &lt;code&gt;python&lt;/code&gt;, e si possono fare cose bellissime con poco sforzo.&lt;/p&gt;&#xA;&lt;p&gt;E una volta fatte, perché tenerli per se e non condividerli, magari proprio qui? L&amp;rsquo;impulso iniziale me l&amp;rsquo;ha dato Federico &amp;ldquo;frix&amp;rdquo; Morchio durante una discussione sul canale &lt;a href=&#34;https://goedel.slack.com&#34;&gt;Goedel&lt;/a&gt; di &lt;a href=&#34;https://slack.com/&#34;&gt;Slack&lt;/a&gt; gestito dal sempre ottimo &lt;a href=&#34;http://macintelligence.org/&#34;&gt;Lucio Bragagnolo&lt;/a&gt; (aka&amp;hellip; oops, &lt;a href=&#34;http://blog.terminologiaetc.it/2017/12/18/significato-abbreviazione-inglese-aka/&#34;&gt;noto anche come&lt;/a&gt; Lux, Loox e tanti altri alias).&lt;/p&gt;&#xA;&lt;p&gt;Attenzione! Questo e i futuri post sull&amp;rsquo;argomento &lt;strong&gt;non saranno&lt;/strong&gt; delle introduzioni a &lt;code&gt;bash&lt;/code&gt;, a &lt;code&gt;python&lt;/code&gt;, al Terminale di macOS (tendo sempre a dimenticare che non si chiama più OS X!), per quelle ci sono un sacco di ottime guide in rete. Chi vuole fare in fretta può iniziare leggendo la mia piccola guida a &lt;code&gt;bash&lt;/code&gt; di qualche anno fa, &lt;a href=&#34;https://melabit.wordpress.com/2014/11/06/script-di-shell-in-os-x/&#34;&gt;Script di shell in OS X&lt;/a&gt; e magari anche &lt;a href=&#34;https://melabit.wordpress.com/2016/12/18/compleanno-con-permessi/&#34;&gt;Compleanno con permessi&lt;/a&gt;, la ripresa di un vecchio post sull&amp;rsquo;ormai defunto &lt;a href=&#34;https://web.archive.org/web/20120102191652/http://www.macworld.it/ping&#34;&gt;Ping&lt;/a&gt; che di fatto mi ha fatto iniziare l&amp;rsquo;esperienza di blogger.&lt;/p&gt;&#xA;&lt;p&gt;Cominciamo con un antipasto veloce, una cosa apparentemente inutile (o quasi), ma che serve a dare una idea delle potenzialità di &lt;code&gt;bash&lt;/code&gt; e di come, partendo da un&amp;rsquo;idea semplice, si possa trasformarla a poco a poco in qualcosa di più pratico e adatto ad un uso quotidiano.&lt;/p&gt;&#xA;&lt;h4 id=&#34;manipolare-i-nomi-dei-file&#34;&gt;Manipolare i nomi dei file&lt;/h4&gt;&#xA;&lt;p&gt;La prima cosa che faccio quando inizio a scrivere un nuovo post è creare un file Markdown con i &lt;em&gt;metadati&lt;/em&gt; (titolo, data di pubblicazione, categoria e tag, chi usa Jekyll o Octopress sa di cosa parlo), a cui assegno un nome temporaneo. Una volta deciso il titolo definitivo, rinomino il file in un modo più razionale, in modo che possa ritrovarlo facilmente.&lt;/p&gt;&#xA;&lt;p&gt;Per farlo seguo la &lt;a href=&#34;https://jekyllrb.com/docs/posts/&#34;&gt;convenzione sui nomi dei file&lt;/a&gt; di Jekyll,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; secondo la quale il nome del file deve essere scritto come &lt;code&gt;YYYY-MM-DD-titolo-del-post.md&lt;/code&gt;, dove &lt;code&gt;YYYY&lt;/code&gt; indica l&amp;rsquo;anno, &lt;code&gt;MM&lt;/code&gt; il mese e &lt;code&gt;DD&lt;/code&gt; il giorno di pubblicazione (espressi rispettivamente con quattro e due cifre) e parole e numeri vanno separati con un trattino invece che con uno spazio. Sembra una cosa inutilmente complicata, ma permette di tenere ordinati i file in base alla data anche quando se ne modifica il contenuto in un secondo tempo. E comunque, evitare di utilizzare gli spazi nei nomi dei file è ancora oggi la cosa più razionale da fare nei sistemi basati su Unix come macOS.&lt;/p&gt;&#xA;&lt;p&gt;Per la data non ci sono problemi, nei metadati è già scritta nel formato &lt;em&gt;giusto&lt;/em&gt;, per cui è sufficiente copiarla ed incollarla direttamente nel nome del file tramite il Finder. Ma il titolo? Potrei usare il Finder anche per il titolo, inserendolo dopo la data nel nome del file e sostituendo a mano gli spazi con i trattini. Però è facile sbagliare, soprattutto quando il titolo è lungo. Ancora più facile è non essere consistenti, usando ogni volta una forma leggermente diversa e mandando a pallino i vantaggi dati dall&amp;rsquo;utilizzare nomi di file ben definiti.&lt;/p&gt;&#xA;&lt;p&gt;E poi, vuoi mettere il divertimento di farlo fare a &lt;code&gt;bash&lt;/code&gt;?&lt;/p&gt;&#xA;&lt;h4 id=&#34;un-pezzo-alla-volta&#34;&gt;Un pezzo alla volta&lt;/h4&gt;&#xA;&lt;p&gt;Prendiamo come esempio il titolo di un &lt;a href=&#34;https://melabit.wordpress.com/2018/01/20/la-privacy-al-tempo-dell-internet-of-things-gran-finale/&#34;&gt;post&lt;/a&gt; di qualche mese fa, &amp;ldquo;La privacy al tempo dell&amp;rsquo;Internet of Things: gran finale&amp;rdquo;. Per trasformare il titolo originale in una sequenza di parole separate da trattini è sufficiente lanciare il Terminale ed eseguire il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | sed &amp;quot;s/ /-/g&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove &lt;code&gt;echo&lt;/code&gt; scrive la stringa nel Terminale e la invia tramite il &lt;code&gt;|&lt;/code&gt; (&lt;em&gt;pipe&lt;/em&gt;) a &lt;code&gt;sed&lt;/code&gt;, che si occupa di cercare tutti gli spazi e di sostituirli con un trattino, ottenendo&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;La-privacy-al-tempo-dell&#39;Internet-of-Things:-gran-finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Non male, ma ci sono due o tre cosette da sistemare.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Problema numero 1 (banale)&lt;/strong&gt;. Il formato di Jekyll prevede implicitamente che il nome del file sia scritto tutto in minuscolo. Personalmente trovo che questa forma sia più gradevole, ma è anche utile a semplificare e a rendere univoco l&amp;rsquo;ordinamento dei file (una fissazione, lo so, ma quando si maneggiano tantissimi file ogni giorno diventa una cosa fondamentale per lavorare meglio). Si può fare così&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | tr &amp;quot;[:upper:]&amp;quot; &amp;quot;[:lower:]&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove &lt;code&gt;tr&lt;/code&gt; trasforma i caratteri maiuscoli (&lt;code&gt;[:upper:]&lt;/code&gt;) in minuscoli (&lt;code&gt;[:lower:]&lt;/code&gt;), ottenendo&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;la privacy al tempo dell&#39;internet of things: gran finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;em&gt;Domanda #1: cosa succede se nel comando precedente si usa &lt;code&gt;tr &amp;quot;[:lower:]&amp;quot; &amp;quot;[:upper:]&amp;quot;&lt;/code&gt;?&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Problema numero 2 (importante)&lt;/strong&gt;. Nei nomi dei file è preferibile usare solo lettere non accentate, numeri e alcuni caratteri di separazione: trattino, underscore e (se proprio dobbiamo) spazio. Se possibile è meglio evitare di usare il punto, che normalmente serve per separare il nome del file vero e proprio dall&amp;rsquo;estensione (caratteristica che è stata usata parecchio per distribuire file contenti virus ma che apparivano legittimi). Tutto gli altri caratteri devono essere rigorosamente evitati, perché spesso hanno significati speciali per il sistema operativo e creano solo guai.&lt;/p&gt;&#xA;&lt;p&gt;Per togliere la punteggiatura possiamo usare la stessa tecnica di sopra,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | sed &amp;quot;s/[[:punct:]]//g&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove in questo caso &lt;code&gt;sed&lt;/code&gt; cerca tutti i caratteri di punteggiatura (&lt;code&gt;[[:punct:]]&lt;/code&gt;) e li sostituisce con&amp;hellip; niente (cioè li toglie), ottenendo in uscita&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;La privacy al tempo dellInternet of Things gran finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;strong&gt;Problema numero 3 (specifico)&lt;/strong&gt;. Il comando di prima rimuove anche gli apostrofi (che è sempre bene evitare di mettere nei nomi dei file, perché potrebbero dare problemi su sistemi operativi meno &lt;em&gt;liberali&lt;/em&gt; di macOS).&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Piuttosto che buttarli via, è preferibile però sostituirli con un trattino, usando ancora una volta &lt;code&gt;sed&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | sed &amp;quot;s/&#39;/-/g&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;che da in uscita&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;La privacy al tempo dell-Internet of Things: gran finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h4 id=&#34;mettiamo-tutto-insieme&#34;&gt;Mettiamo tutto insieme&lt;/h4&gt;&#xA;&lt;p&gt;Usare &lt;code&gt;bash&lt;/code&gt; (o qualunque altra shell di Unix) è un po&amp;rsquo; come usare il Lego dove, mettendo insieme dei piccoli mattoncini di forme e colori diversi, si può costruire una portaerei (o quasi). Con &lt;code&gt;bash&lt;/code&gt; si prendono dei semplici comandi come quelli visti prima, si mettono nell&amp;rsquo;ordine giusto, si collega l&amp;rsquo;output di un comando con l&amp;rsquo;input di quello successivo tramite il &lt;code&gt;|&lt;/code&gt; (&lt;em&gt;pipe&lt;/em&gt;), e alla fine si riescono a fare delle cose anche piuttosto sofisticate.&lt;/p&gt;&#xA;&lt;p&gt;In questo caso, il comando&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;La privacy al tempo dell&#39;Internet of Things: gran finale&amp;quot; | tr &amp;quot;[:upper:]&amp;quot; &amp;quot;[:lower:]&amp;quot; | sed &amp;quot;s/&#39;/ /g&amp;quot; | sed &amp;quot;s/[[:punct:]]//g&amp;quot; | sed &amp;quot;s/ /-/g&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;genera la stringa&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;la-privacy-al-tempo-dell-internet-of-things-gran-finale&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;pronta per essere utilizzata come nome del file.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Domanda #2: Cosa succede se cambio l&amp;rsquo;ordine dei comandi? Perché questo è l&amp;rsquo;ordine migliore per convertire un titolo nel formato desiderato?&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Domanda #3: Perché nel primo &lt;code&gt;sed&lt;/code&gt; questa volta ho sostituito l&amp;rsquo;apostrofo &lt;code&gt;&#39;&lt;/code&gt; con uno spazio (mentre nella descrizione del problema numero 3 avevo usato un trattino)?&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Chi ha avuto la pazienza di leggere fin qui, si starà chiedendo che senso abbia complicarsi la vita con il Terminale e con &lt;code&gt;bash&lt;/code&gt;, quando è molto più veloce modificare il titolo a mano nel Finder.&lt;/p&gt;&#xA;&lt;p&gt;Tutto vero, ma è altrettanto vero che il post è stato più che altro una scusa per introdurre due comandi come &lt;code&gt;sed&lt;/code&gt; e &lt;code&gt;tr&lt;/code&gt;, molto utili ma anche molto poco conosciuti. E poi, partendo da questa base si possono costruire delle cose molto più utili, ma questo lo vedremo la prossima volta.&lt;/p&gt;&#xA;&lt;h5 id=&#34;revisioni&#34;&gt;Revisioni&lt;/h5&gt;&#xA;&lt;p&gt;&lt;strong&gt;3-12-2018&lt;/strong&gt;: Corretta una incongruenza nel testo originale, nel quale veniva usato una volta &lt;code&gt;sed&lt;/code&gt; e un&amp;rsquo;altra &lt;code&gt;tr&lt;/code&gt; per rimuovere i caratteri di punteggiatura.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Che poi è praticamente la stessa convenzione che usa Wordpress per generare i nomi dei post.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;La gestione generale dei caratteri accentati nei nomi dei file è un problema molto più complesso, che è meglio rimandare ad un post specifico sull&amp;rsquo;argomento, ammesso che ci sia interesse per l&amp;rsquo;argomento.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Imparare a programmare per iOS</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/03/12/imparare-a-programmare-per-ios/</link>
      <pubDate>Mon, 12 Mar 2018 12:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/03/12/imparare-a-programmare-per-ios/</guid>
      <description>&lt;img src=&#34;https://dz13w8afd47il.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/4507_5628_iOS%2010%20Programming%20for%20Beginners.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Lo so che tendo spesso a dimenticarlo, ma questo blog dovrebbe essere dedicato soprattutto alla programmazione e al Mac. E allora non posso non segnalare il volume di Craig Clayton, &lt;a href=&#34;https://www.packtpub.com/packt/offers/free-learning&#34;&gt;iOS 10 Programming for Beginners&lt;/a&gt;, edito da &lt;a href=&#34;https://www.packtpub.com/&#34;&gt;Packt&lt;/a&gt; e disponibile oggi (e solo oggi) in download gratuito.&lt;/p&gt;&#xA;&lt;p&gt;Lo so che siamo a iOS 11 e che attendiamo iOS 12, ma sono anche convinto che per un principiante sia meglio concentrarsi sulle funzioni di base del sistema operativo, disponibili anche nelle versioni precedenti di iOS, piuttosto che provare a sfruttare le ultimissime &lt;em&gt;bells and whistles&lt;/em&gt; (in italiano non esiste una espressione equivalente, diciamo più o meno &amp;ldquo;fronzoli&amp;rdquo;, &amp;ldquo;orpelli&amp;rdquo;) messe a disposizione ogni anno dagli ingegneri di Apple.&lt;/p&gt;&#xA;&lt;p&gt;Inoltre, a differenza di tante altre introduzioni alla programmazione per iOS, questo volume usa &lt;a href=&#34;https://developer.apple.com/swift/&#34;&gt;Swift&lt;/a&gt;, il linguaggio di programmazione sviluppato negli ultimi anni da Apple e che sta avendo un successo molto superiore alle aspettative, sia perché funziona su tutte le piattaforme hardware/software dell&amp;rsquo;azienda (quindi non solo macOS e iOS ma anche tvOS e watchOS), sia perché è enormemente più semplice da imparare ed usare di Objective C, il linguaggio usato tradizionalmente per le applicazioni per iOS e per gran parte di quelle per il Mac.&lt;/p&gt;&#xA;&lt;p&gt;Se siete appena appena interessati alla programmazione e ad iOS, secondo me non dovreste farvi sfuggire l&amp;rsquo;occasione.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Script per tutti i giorni: ricapitoliamo</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2018/01/30/script-per-tutti-i-giorni-ricapitoliamo/</link>
      <pubDate>Tue, 30 Jan 2018 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2018/01/30/script-per-tutti-i-giorni-ricapitoliamo/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm4.staticflickr.com/3691/10922273715_cfd864963f_b.jpg&#34; alt=&#34;&#34;&gt;&#xA;&amp;ndash; Foto: &lt;a href=&#34;https://www.flickr.com/photos/ul_digital_library/&#34;&gt;Glucksman Library at Limerick&lt;/a&gt; su Flickr.&lt;/p&gt;&#xA;&lt;p&gt;Prima di proseguire con questa serie dedicata alla scrittura di piccoli script in &lt;code&gt;bash&lt;/code&gt; e affini, mi sembra utile ricapitolare i concetti principali delle prime tre puntate (qui i link alla &lt;a href=&#34;https://melabit.wordpress.com/2018/11/23/script-per-tutti-i-giorni-semplici-modifiche-alle-stringhe-di-testo/&#34;&gt;prima&lt;/a&gt;, &lt;a href=&#34;https://melabit.wordpress.com/2018/12/05/script-per-tutti-i-giorni-dalla-linea-di-comando-al-programma/&#34;&gt;seconda&lt;/a&gt; e &lt;a href=&#34;https://melabit.wordpress.com/2018/12/30/script-per-tutti-i-giorni-shell-e-parametri/&#34;&gt;terza&lt;/a&gt; puntata).&lt;/p&gt;&#xA;&lt;h4 id=&#34;case-e-cartelle&#34;&gt;Case e cartelle&lt;/h4&gt;&#xA;&lt;p&gt;Come tutti i sistemi basati su Unix, anche macOS è progettato per essere usato da più utenti, anche in contemporanea. Nella pratica non è così, nella maggior parte dei casi il Mac è usato da un solo utente e solo di rado vengono attivati degli account per più di tre o quattro utenti, però la funzionalità c&amp;rsquo;è.&lt;/p&gt;&#xA;&lt;p&gt;Di conseguenza ciascun utente del Mac dispone di un&amp;rsquo;area personale dove salvare tutti i documenti, dati e file di configurazione, nettamente separata da quelle degli eventuali altri utenti del sistema. Non a caso quest&amp;rsquo;area personale è denominata &lt;code&gt;Home&lt;/code&gt;, la &lt;em&gt;casa&lt;/em&gt; dell&amp;rsquo;utente.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Dal punto di vista pratico l&amp;rsquo;area personale di ciascun utente è costituita da una cartella, rappresentata dall&amp;rsquo;icona di una casetta e denominata con il &lt;code&gt;nome account&lt;/code&gt; (o &lt;code&gt;nome breve&lt;/code&gt;), cioè con il nome utilizzato per fare il login sul Mac, che viene assegnato all&amp;rsquo;utente una volta per tutte al momento della creazione dell&amp;rsquo;account. All&amp;rsquo;interno di questa cartella principale ci sono un certo numero di cartelle standard gestite automaticamente dal sistema operativo,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; ma niente impedisce di definire delle ulteriori cartelle personali. Io ad esempio uso la cartella &lt;code&gt;Documenti&lt;/code&gt; solo per i file generati automaticamente da certe applicazioni e conservo tutti i miei documenti in alcune cartelle ben definite contenute nella mia &lt;code&gt;Home&lt;/code&gt;, dentro le quali ci sono un gran numero di sottocartelle più specifiche.&lt;/p&gt;&#xA;&lt;p&gt;Una delle cartelle contenute nella mia &lt;code&gt;Home&lt;/code&gt; è &lt;code&gt;Development&lt;/code&gt;, che uso  da sempre per salvare i progetti generici relativi allo sviluppo software (quelli più strettamente collegati alla mia attività lavorativa sono altrove). Proprio per questo ho preferito salvare in questa cartella anche tutti i piccoli programmi proposti nel corso di questa serie, consigliando i lettori di fare altrettanto in modo da seguire più facilmente gli esempi riportati. Chi preferisce usare una cartella diversa dovrà ricordarsi di modificare di conseguenza i percorsi dei comandi.&lt;/p&gt;&#xA;&lt;p&gt;Già che siamo in tema di &lt;em&gt;cartelle&lt;/em&gt;, ribadisco quello che ho scritto nella terza puntata. I termini &lt;em&gt;directory&lt;/em&gt; e &lt;em&gt;cartella&lt;/em&gt; sono perfettamente equivalenti, io preferisco usare il primo ma so benissimo che nell&amp;rsquo;uso comune prevale nettamente il secondo, non a caso in tutte le interfacce grafiche l&amp;rsquo;icona che rappresenta la directory è proprio quella di una cartella di documenti. Ho deciso quindi di uniformarmi all&amp;rsquo;uso comune e usare il termine &amp;ldquo;cartella&amp;rdquo; nel testo discorsivo degli articoli, ma di continuare ad utilizzare &amp;ldquo;directory&amp;rdquo; quando il discorso si fa più tecnico, ad esempio ogni volta che tratterò di comandi dei &lt;code&gt;bash&lt;/code&gt; e del Terminale.&lt;/p&gt;&#xA;&lt;h4 id=&#34;il-terminale-di-macos&#34;&gt;Il Terminale di macOS&lt;/h4&gt;&#xA;&lt;p&gt;Chi legge i miei post sa che uso moltissimo il Terminale, l&amp;rsquo;interfaccia  a linea di comando di macOS, e lo considero uno strumento insostituibile quando si tratta di eseguire compiti complessi e ripetitivi. Provate ad usare un programma con interfaccia grafica per convertire un centinaio di immagini da un formato ad un altro, sovrapponendo a ciascuna immagine una scritta variabile e poi ditemi.&lt;/p&gt;&#xA;&lt;p&gt;In macOS il Terminale si trova nella cartella &lt;code&gt;Utility&lt;/code&gt;, posta all&amp;rsquo;interno della cartella &lt;code&gt;Applicazioni&lt;/code&gt;, un percorso che possiamo scrivere in modo più compatto come &lt;code&gt;Applicazioni &amp;amp;#62; Utility&lt;/code&gt;, dove il simbolo &lt;code&gt;&amp;amp;#62;&lt;/code&gt; indica il passaggio da una cartella ad un&amp;rsquo;altra contenuta al suo interno. Se lo usate spesso e vi secca doverlo andare a cercare ogni volta, aggiungetelo al Dock e vi basterà un click per lanciarlo.&lt;/p&gt;&#xA;&lt;p&gt;La prima (o la prossima) volta che usate il Terminale fatevi un favore e cambiate un paio di cosette nella sua configurazione standard.&lt;/p&gt;&#xA;&lt;p&gt;Innanzi tutto lanciate le Preferenze del Terminale, scegliete un profilo più gradevole di quello tutto bianco di base e rendetelo il profilo di default (io preferisco Ocean o Homebrew, ma è una questione di gusti personali). Per farlo, cliccate sull&amp;rsquo;icona Profili situata nella barra degli strumenti, selezionate dal pannello laterale sinistro il profilo che preferite e infine cliccate sul tasto &lt;code&gt;Default&lt;/code&gt; posto proprio in fondo al pannello. Se volete provare i vari profili prima di decidere quale vi piace di più, vi basta fare un doppio click sulle anteprime situate nel pannello laterale.&lt;/p&gt;&#xA;&lt;p&gt;Chissà perché Apple ha scelto per il Terminale una impostazione di default di appena 80 caratteri per 24 righe (80x24), forse voleva ricordarci come poteva essere lavorare sullo schermo di un &lt;a href=&#34;https://it.wikipedia.org/wiki/Apple_II&#34;&gt;Apple II&lt;/a&gt; (già in versione &amp;ldquo;espansa&amp;rdquo;)! Ma siamo in pieni anni 2000 e un Terminale più grande è decisamente più comodo. Per cui, una volta selezionato il profilo grafico preferito, potete cambiare le dimensioni della finestra del Terminale selezionando il pannello &lt;code&gt;Finestra&lt;/code&gt; nell&amp;rsquo;area centrale delle Preferenze del Terminale e inserendo le dimensioni che preferite, in termini di righe e colonne. Io in genere uso finestre di Terminale da 120 colonne per 40 righe (120x40), forse mi ricorda qualcosa ma comunque mi sembra un buon equilibrio fra ingombro sullo schermo e comodità d&amp;rsquo;uso.&lt;/p&gt;&#xA;&lt;p&gt;Se non avete idea di quanto queste dimensioni in righe e colonne si traducano in dimensioni reali sullo schermo, rilanciate il Terminale (per attivare il profilo di default) e allargate la finestra finché non diventa grande abbastanza per i vostri gusti, esattamente come fareste con qualunque altra applicazione per macOS. Per rendere queste dimensioni le nuove impostazioni di default, non dimenticate di cliccare sulla voce &lt;code&gt;Utilizza impostazioni come default&lt;/code&gt; del menu &lt;code&gt;Shell&lt;/code&gt; (che potrei scrivere anche come &lt;code&gt;Shell &amp;amp;#62; Utilizza impostazioni come default&lt;/code&gt;, dove il simbolo &lt;code&gt;&amp;amp;#62;&lt;/code&gt; serve in questo caso a separare le voci di menu da selezionare in sequenza).&lt;/p&gt;&#xA;&lt;h4 id=&#34;il-prompt-del-terminale&#34;&gt;Il prompt del Terminale&lt;/h4&gt;&#xA;&lt;p&gt;Se l&amp;rsquo;avete chiuso, lanciate di nuovo il Terminale e guardate con attenzione la finestra che appare. È praticamente vuota, tranne due brevi righe di testo. Se non avete fatto altre modifiche alla configurazione del Terminale rispetto a quelle proposte qui sopra, nella prima riga c&amp;rsquo;è la data e l&amp;rsquo;ora correnti con l&amp;rsquo;indicazione del numero del terminale virtuale correntemente aperto, &lt;code&gt;ttys001&lt;/code&gt;, &lt;code&gt;ttys002&lt;/code&gt; e così via. Il Terminale di macOS, infatti, non è altro che un emulatore software dei terminali &lt;em&gt;fisici&lt;/em&gt; con i quali, fino agli anni &amp;lsquo;80, ci si collegava ai grossi computer delle università o delle aziende mediante un protocollo di comunicazione seriale analogo a quello delle &lt;a href=&#34;https://it.wikipedia.org/wiki/Telescrivente&#34;&gt;telescriventi&lt;/a&gt;. In inglese la telescrivente si chiama &lt;em&gt;Teletype&lt;/em&gt; o &lt;em&gt;TTY&lt;/em&gt; e l&amp;rsquo;acronimo è rimasto ancora in uso per indicare appunto i terminali, ormai diventati solo &lt;em&gt;virtuali&lt;/em&gt;, dei sistemi Unix come Linux e macOS.&lt;/p&gt;&#xA;&lt;p&gt;Nella seconda riga invece compare il nome del vostro Mac, quello che avete definito nel pannello &lt;code&gt;Condivisione&lt;/code&gt; delle &lt;code&gt;Preferenze di Sistema&lt;/code&gt;, seguito dai due punti e dal nome della directory corrente, che in questo momento dovrebbe essere la &lt;code&gt;Home&lt;/code&gt; del vostro account, rappresentata dal simbolo tilde, &lt;code&gt;~&lt;/code&gt; (in macOS la tilde si scrive premendo ALT-5). Subito dopo il nome della directory corrente c&amp;rsquo;è uno spazio, il vostro &lt;code&gt;nome account&lt;/code&gt; e infine il simbolo del dollaro, &lt;code&gt;$&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;nome-computer:directory nome-account$ &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Questa riga si chiama il &lt;code&gt;prompt&lt;/code&gt; del Terminale, riesce a dare parecchie informazioni utili in modo compatto e, volendo, può essere &lt;a href=&#34;http://osxdaily.com/2006/12/11/how-to-customize-your-terminal-prompt/&#34;&gt;modificata a piacere&lt;/a&gt; (mai capito perché, però se queste cose vi piacciono potete usare questo &lt;a href=&#34;http://bashrcgenerator.com/&#34;&gt;generatore online&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Quando si descrivono i comandi della shell (che quasi sempre è &lt;code&gt;bash&lt;/code&gt;), il prompt del Terminale viene rappresentato spesso con il solo simbolo &lt;code&gt;$&lt;/code&gt;, tralasciando tutto quello che c&amp;rsquo;è prima. Non bisogna mai dimenticare che il &lt;code&gt;$&lt;/code&gt; (o l&amp;rsquo;intero prompt) serve solo a mettere in evidenza che stiamo usando il Terminale ma non fa parte dei comandi della shell, per cui non dobbiamo mai scriverlo quando interagiamo con il Terminale, magari copiando i comandi dagli articoli di questa serie.&lt;/p&gt;&#xA;&lt;h4 id=&#34;pillole-di-bash&#34;&gt;Pillole di bash&lt;/h4&gt;&#xA;&lt;p&gt;E veniamo finalmente ad alcuni fra i comandi principali di &lt;code&gt;bash&lt;/code&gt;. Primo fra tutti &lt;code&gt;cd&lt;/code&gt; che permette di muoversi fra le directory del disco rigido. Il comando &lt;code&gt;cd&lt;/code&gt; deve essere seguito dal percorso completo da seguire per arrivare alla directory desiderata, per cui&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd Development&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ci fa passare nella cartella &lt;code&gt;Development&lt;/code&gt; (supponendo di partire dalla &lt;code&gt;Home&lt;/code&gt;), mentre&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd Music/iTunes&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ci fa andare direttamente nella cartella &lt;code&gt;iTunes&lt;/code&gt; contenuta all&amp;rsquo;interno di &lt;code&gt;Music&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Se ci sentiamo persi, possiamo usare&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;per tornare nella nostra &lt;code&gt;Home&lt;/code&gt;, oppure&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ pwd&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;per stampare nel Terminale il percorso completo della directory in cui ci troviamo. Tutti i percorsi riportati da &lt;code&gt;pwd&lt;/code&gt; partono dalla directory &lt;code&gt;/&lt;/code&gt;, la &lt;em&gt;radice&lt;/em&gt; (o &lt;em&gt;root&lt;/em&gt;) del disco rigido,&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; per cui se ci troviamo nella &lt;code&gt;Home&lt;/code&gt; dell&amp;rsquo;utente &lt;code&gt;alice&lt;/code&gt;, l&amp;rsquo;esecuzione di &lt;code&gt;pwd&lt;/code&gt; restituirà&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ pwd&#xA;/Users/alice&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove, come abbiamo già visto, &lt;code&gt;alice&lt;/code&gt; è il &lt;code&gt;nome account&lt;/code&gt; dell&amp;rsquo;utente che ha effettuato il login sul Mac. Da notare che in macOS tutte le &lt;code&gt;Home&lt;/code&gt; degli utenti si trovano all&amp;rsquo;interno della directory &lt;code&gt;/Users&lt;/code&gt;, a differenza della maggior parte degli altri sistemi operativi basati su Unix (Linux e i vari BSD) che sono più banali ed usano &lt;code&gt;/home&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;E per sapere qual&amp;rsquo;è il nostro &lt;code&gt;nome account&lt;/code&gt;? C&amp;rsquo;è un comando anche per questo,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ whoami&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;forse scritto da qualche filosofo esistenzialista.&lt;/p&gt;&#xA;&lt;p&gt;Con il comando &lt;code&gt;cd&lt;/code&gt; si utilizzano spesso delle abbreviazioni molto comode: &lt;code&gt;~&lt;/code&gt; che indica la nostra directory &lt;code&gt;Home&lt;/code&gt;, &lt;code&gt;.&lt;/code&gt; che indica la directory corrente (quella riportata da &lt;code&gt;pwd&lt;/code&gt;) e &lt;code&gt;..&lt;/code&gt; che invece indica la directory che contiene la directory corrente. Se in questo momento ci troviamo nella directory &lt;code&gt;~/Music/iTunes&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ..&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ci fa fare un passo &lt;em&gt;indietro&lt;/em&gt;  tornando a &lt;code&gt;~/Music&lt;/code&gt;, mentre&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ci fa tornare nella nostra &lt;code&gt;Home&lt;/code&gt; (ma basta anche il solo &lt;code&gt;cd&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Un altro comando fondamentale di &lt;code&gt;bash&lt;/code&gt; è &lt;code&gt;echo&lt;/code&gt;, che stampa una stringa sul Terminale&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;questa è una stringa&amp;quot;&#xA;questa è una stringa&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Non è nemmeno necessario racchiudere la stringa fra virgolette, &lt;code&gt;echo&lt;/code&gt; stamperà sul Terminale tutto ciò che viene immediatamente dopo il comando, quindi va altrettanto bene scrivere&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo questa è una stringa&#xA;questa è una stringa&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;È molto comune utilizzare &lt;code&gt;echo&lt;/code&gt; per scrivere direttamente in un file invece che sul Terminale tramite l&amp;rsquo;operatore di redirezione &lt;code&gt;&amp;amp;#62;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;questa è una stringa&amp;quot; &amp;amp;#62; file.txt&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Se il file &lt;code&gt;file.txt&lt;/code&gt; non esiste, &lt;code&gt;echo&lt;/code&gt; lo crea da zero e ci scrive dentro la stringa, altrimenti sovrascrive il contenuto precedente di &lt;code&gt;file.txt&lt;/code&gt; e lo sostituisce con la nuova stringa. Se vogliamo che il nome del file da creare contenga degli spazi lo dobbiamo racchiudere fra virgolette, non importa se semplici o doppie&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;questa è una stringa&amp;quot; &amp;amp;#62; &amp;quot;file con spazi.txt&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Per scrivere con &lt;code&gt;echo&lt;/code&gt; in un file senza perdere il contenuto già esistente, dobbiamo usare l&amp;rsquo;operatore &lt;code&gt;&amp;amp;#62;&amp;amp;#62;&lt;/code&gt; che aggiunge (&lt;em&gt;append&lt;/em&gt;) una nuova stringa alla fine del file &lt;code&gt;file.txt&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;questa è una stringa&amp;quot; &amp;amp;#62;&amp;amp;#62; file.txt&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Anche in questo caso, se il file &lt;code&gt;file.txt&lt;/code&gt; non esiste &lt;code&gt;echo&lt;/code&gt; lo crea da zero e ci scrive dentro la stringa.&lt;/p&gt;&#xA;&lt;p&gt;Gli operatori di redirezione &lt;code&gt;&amp;amp;#62;&lt;/code&gt; e &lt;code&gt;&amp;amp;#62;&amp;amp;#62;&lt;/code&gt; assomigliano moltissimo ad un altro operatore che abbiamo incontrato più volte nel corso delle puntate precedenti, il &lt;code&gt;|&lt;/code&gt; (&lt;em&gt;pipe&lt;/em&gt;), che serve a fare in modo che l’output di un comando venga utilizzato come input del comando successivo. Come in questo caso&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;questa è una stringa&amp;quot; | tr &amp;quot;[:lower:]&amp;quot; &amp;quot;[:upper:]&amp;quot;&#xA;QUESTA È UNA STRINGA&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove il primo comando &lt;code&gt;echo&lt;/code&gt; scrive una stringa e la invia a &lt;code&gt;tr&lt;/code&gt; che a sua volta la converte in caratteri maiuscoli e stampa il risultato finale sullo schermo.&lt;/p&gt;&#xA;&lt;p&gt;Sempre restando in tema di file, ci sono due comandi importantissimi ma piuttosto complicati, &lt;code&gt;chmod&lt;/code&gt; e &lt;code&gt;chown&lt;/code&gt;, che permettono rispettivamente di cambiare i permessi di lettura (&lt;code&gt;r&lt;/code&gt;), scrittura (&lt;code&gt;w&lt;/code&gt;) ed esecuzione (&lt;code&gt;x&lt;/code&gt;) dei file, e di assegnare la &lt;em&gt;proprietà&lt;/em&gt; di un file ad un determinato utente o gruppo di utenti. In questo momento non ha senso entrare nei dettagli dei due comandi, per ora basterà sapere che&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u+x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;rende lo script &lt;code&gt;script.sh&lt;/code&gt; eseguibile da parte dell&amp;rsquo;utente corrente del Mac, mentre&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u-x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;rimuove l&amp;rsquo;autorizzazione precedente. Invece&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod a+x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;rende lo script eseguibile da tutti gli utenti e il suo contrario&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod a-x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;impedisce a tutti gli utenti, quindi anche a noi stessi!, di eseguire lo script in questione.&lt;/p&gt;&#xA;&lt;p&gt;Per quanto riguarda &lt;code&gt;chown&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chown alice file.txt&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;rende &lt;code&gt;file.txt&lt;/code&gt; di proprietà dell&amp;rsquo;utente &lt;code&gt;alice&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I permessi di un file si possono verificare tramite &lt;code&gt;ls&lt;/code&gt;, un comando utilizzato di continuo in una qualunque sessione del Terminale per mostrare il contenuto di una directory, cioè tutti i file e le directory (per Unix non c&amp;rsquo;è differenza) che si trovano all&amp;rsquo;interno di una directory data. La directory su cui deve operare &lt;code&gt;ls&lt;/code&gt; va indicata subito dopo il comando, se non scriviamo niente &lt;code&gt;ls&lt;/code&gt; mostra il contenuto della directory corrente.&lt;/p&gt;&#xA;&lt;p&gt;Il comando &lt;code&gt;ls&lt;/code&gt; &lt;em&gt;liscio&lt;/em&gt; mostra il contenuto di una directory in forma di tabella, e l&amp;rsquo;unico modo per distinguere i file dalle directory è tramite l&amp;rsquo;estensione: normalmente i nomi dei file terminano con una estensione costituita da un punto e da tre lettere mentre le directory non hanno estensione (ma non è detto che sia sempre così). Ad esempio&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls ~&#xA;Applications  Documentation Library       My Documents  Public        Tmp&#xA;Desktop       Documents     Movies        Papers        Research      bin&#xA;Development   Downloads     Music         Pictures      Sites&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;elenca tutte i file e le directory contenuti nella &lt;code&gt;Home&lt;/code&gt; del mio Mac (in effetti compaiono solo delle directory). Usato così, &lt;code&gt;ls&lt;/code&gt; serve a poco. Molto meglio&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls -l&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;che mostra il contenuto di una directory in forma di lista invece che di tabella, riportando in più una serie di informazioni dettagliate su ciascun file (o directory).&lt;/p&gt;&#xA;&lt;p&gt;In particolare, la prima colonna contiene una sequenza di 10 simboli &amp;ndash; in genere &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;d&lt;/code&gt;, &lt;code&gt;r&lt;/code&gt;, &lt;code&gt;w&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt;, qualche rara volta anche &lt;code&gt;s&lt;/code&gt; o &lt;code&gt;S&lt;/code&gt; &amp;ndash; che ci dicono se abbiamo a che fare con un file o una directory e quali sono i permessi associati al file stesso (o alla directory).&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;  Il trattino, &lt;code&gt;-&lt;/code&gt;, indica che il permesso corrispondente non è assegnato. I dettagli possono essere &lt;a href=&#34;https://en.wikibooks.org/wiki/A_Quick_Introduction_to_Unix/Permissions&#34;&gt;letti qui&lt;/a&gt; o su una qualsiasi guida introduttiva a &lt;code&gt;bash&lt;/code&gt;, come quelle riportate nella Bibliografia qui sotto. A noi basta sapere che la &lt;code&gt;d&lt;/code&gt; in prima posizione indica una directory e che se troviamo una &lt;code&gt;x&lt;/code&gt; nella quarta, settima o decima posizione significa che il file è eseguibile rispettivamente dall&amp;rsquo;utente corrente, dagli utenti che fanno parte del suo stesso gruppo o infine da tutti gli utenti del Mac.&lt;/p&gt;&#xA;&lt;p&gt;Facciamo un esempio pratico: supponiamo di aver creato nella cartella &lt;code&gt;Development&lt;/code&gt; lo script &lt;code&gt;script.sh&lt;/code&gt;, contenente una serie di comandi &lt;code&gt;bash&lt;/code&gt;; appena creato lo script ha i permessi attribuiti di default a un file generico&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls -al script.sh &#xA;-rw-r--r--  1 nome-account  staff  0 Jan 25T22:07:00 script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e poiché non troviamo nessuna &lt;code&gt;x&lt;/code&gt;, significa che non può essere eseguito da nessun utente. Per renderlo eseguibile dall&amp;rsquo;utente attuale del Mac&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod u+x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;come si vede eseguendo di nuovo &lt;code&gt;ls&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls -al script.sh &#xA;-rwxr--r--  1 nome-account  staff  0 Jan 25T22:07:00 script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e notando che il &lt;code&gt;-&lt;/code&gt; in quarta posizione è diventato una &lt;code&gt;x&lt;/code&gt;. Se invece rendiamo il file eseguibile a tutti gli utenti con&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod a+x script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;l&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt; sarà&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls -al script.sh &#xA;-rwxr-xr-x  1 nome-account  staff  0 Jan 25T22:07:00 script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove si vede che i trattini in quarta, settima o decima posizione sono diventati delle &lt;code&gt;x&lt;/code&gt;. Per riportare tutto alla situazione iniziale&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ chmod a-x script.sh &#xA;$ ls -al script.sh &#xA;-rw-r--r--  1 nome-account  staff  0 Jan 25T22:07:00 script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Prima di concludere questa lunghissima introduzione a &lt;code&gt;bash&lt;/code&gt;, ecco alcuni comandi relativi alla creazione e cancellazione di file e directory. Per creare un file ci sono cento modi diversi, abbiamo già visto come farlo con &lt;code&gt;echo&lt;/code&gt;, ma possiamo utilizzare anche il comando &lt;code&gt;touch&lt;/code&gt;, che crea un file vuoto da utilizzare in un secondo momento, per cui&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ touch new_file.txt&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;crea il file vuoto &lt;code&gt;new_file.txt&lt;/code&gt; nella directory corrente.&lt;/p&gt;&#xA;&lt;p&gt;Per rimuovere un file si usa invece &lt;code&gt;rm&lt;/code&gt; seguito dal nome del file, quindi&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ rm new_file.txt&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;cancella il file che abbiamo appena creato con &lt;code&gt;touch&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Analogamente, per creare una directory si usa &lt;code&gt;mkdir&lt;/code&gt; (abbreviazione di &lt;em&gt;make directory&lt;/em&gt;), per rimuoverla &lt;code&gt;rmdir&lt;/code&gt; (abbreviazione di &lt;em&gt;remove directory&lt;/em&gt;), seguiti in entrambi i casi dal nome della directory da creare o da rimuovere&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ mkdir nuova_directory&#xA;$ rmdir nuova_directory&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Anche in questo caso, se il nome della directory da creare (o da rimuovere) contiene degli spazi, deve essere racchiuso fra virgolette semplici o doppie. Per evitare errori che potrebbero essere disastrosi, si può rimuovere una directory solo se è vuota, cioè se non contiene altri file o altre directory.&lt;/p&gt;&#xA;&lt;p&gt;Credo che per ora possa bastare&amp;hellip;&lt;/p&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;Questo articolo è cresciuto ben oltre le previsioni iniziali. Purtroppo era necessario farlo, sia per ricapitolare in modo organico le cose dette nelle prime tre puntate, sia per creare un linguaggio di base che permettesse di andare avanti più spediti, evitando di perdersi in troppi dettagli che rallentano e rendono più pesante l&amp;rsquo;esposizione. Alla prossima puntata con qualche cosa di nuovo e, spero, di interessante!&lt;/p&gt;&#xA;&lt;h4 id=&#34;bibliografia&#34;&gt;Bibliografia&lt;/h4&gt;&#xA;&lt;p&gt;I titoli su &lt;code&gt;bash&lt;/code&gt; si sprecano. Fra questi vorrei segnalare due guide in italiano e due in inglese. Purtroppo il materiale di qualità in italiano è scarso e le traduzioni dall&amp;rsquo;inglese sono per forza di cose molto più datate delle versioni originali (lo potete notare chiaramente confrontando le date delle versioni più recenti in italiano e in inglese della guida di Cooper), per cui è quasi sempre preferibile consultare i manuali e i tutorial originali in inglese. Per fortuna l&amp;rsquo;inglese &lt;em&gt;tecnico&lt;/em&gt; è molto comprensibile e non ci vuole molto per riuscire a leggerlo in modo fluido. Certo, se la scuola non facesse di tutto per renderlo odioso, le cose sarebbero più semplici per tutti.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Garrels, &lt;a href=&#34;http://codex.altervista.org/guidabash/guidabash_1_11.pdf&#34;&gt;La guida di Bash per i principianti&lt;/a&gt;, 2008.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Cooper, &lt;a href=&#34;http://www.pluto.it/sites/default/files/ildp/guide/abs/index.html&#34;&gt;Guida avanzata di scripting Bash&lt;/a&gt;, rev. 4.1, 2006.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Cooper, &lt;a href=&#34;https://www.tldp.org/LDP/abs/html/index.html&#34;&gt;Advanced Bash-Scripting Guide&lt;/a&gt;, rev. 10, 2014.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Wikibooks, &lt;a href=&#34;https://en.wikibooks.org/wiki/A_Quick_Introduction_to_Unix&#34;&gt;A Quick Introduction to Unix&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Purtroppo nella versione italiana di macOS è stata tradotta con &lt;code&gt;Inizio&lt;/code&gt;, che non rende altrettanto bene l&amp;rsquo;idea. Io non posso soffrire il termine &lt;code&gt;inizio&lt;/code&gt; e userò sempre &lt;code&gt;Home&lt;/code&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Fra cui &lt;code&gt;Filmati&lt;/code&gt;, &lt;code&gt;Immagini&lt;/code&gt; e &lt;code&gt;Musica&lt;/code&gt; per i file multimediali, &lt;code&gt;Download&lt;/code&gt; per i file scaricati da internet, &lt;code&gt;Documenti&lt;/code&gt; per i file personali e &lt;code&gt;Scrivania&lt;/code&gt; per i (troppi) file buttati alla rinfusa sul Desktop, cioè sulla scrivania virtuale del Mac.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;O meglio, del &lt;em&gt;file system&lt;/em&gt; del disco rigido. Il disco rigido in sé è solo un oggetto hardware che non serve a molto finché non lo si &lt;em&gt;formatta&lt;/em&gt;, creando una struttura dati (il &lt;em&gt;file system&lt;/em&gt;, appunto) che possa essere utilizzata dal sistema operativo per memorizzare i file.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;In macOS possono anche essere presenti i simboli &lt;code&gt;+&lt;/code&gt; o &lt;code&gt;@&lt;/code&gt; nell&amp;rsquo;undicesima posizione della colonna.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Una linea di codice</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2017/09/07/una-linea-di-codice/</link>
      <pubDate>Thu, 07 Sep 2017 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2017/09/07/una-linea-di-codice/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://melabit.wordpress.com/2017/08/31/cray-1-a-confronto/&#34;&gt;A proposito di programmazione&lt;/a&gt;, cosa si può fare con una linea di codice? A volte si può fare moltissimo, come dimostra &lt;a href=&#34;http://www.p01.org/128b_raytraced_checkboard/&#34;&gt;questa singola linea di codice JavaScript&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;[code language=&amp;ldquo;javascript&amp;rdquo; htmlscript=true]&#xA;&lt;pre id=p&gt;&lt;script&gt;n=setInterval(&amp;ldquo;for(n+=7,i=k,P=&amp;lsquo;p.\n&amp;rsquo;;i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&amp;amp;1:2])j=k/i;p.innerHTML=P&amp;rdquo;,k=64)&lt;/script&gt;&#xA;[/code]&#xA;&lt;/pre&gt;&lt;/p&gt;&#xA;&lt;p&gt;Sono appena 128 caratteri, meno di un tweet, che però riescono a produrre questa bella immagine dinamica.&lt;/p&gt;&#xA;&lt;img src=&#34;https://www.alexkras.com/wp-content/uploads/ray.gif&#34; alt=&#34;&#34;&gt;&lt;p&gt;Ma come fa?&lt;/p&gt;&#xA;&lt;p&gt;Alex Kras ha accettato la sfida e ha scritto un bellissimo articolo, &lt;a href=&#34;https://www.alexkras.com/reverse-engineering-one-line-of-javascript&#34;&gt;&lt;em&gt;Reverse Engineering One Line of JavaScript&lt;/em&gt;&lt;/a&gt;, in cui descrive il suo viaggio nei meandri di un codice solo apparentemente semplice.&lt;/p&gt;&#xA;&lt;p&gt;È una splendida dimostrazione di capacità tecnica, sia di chi ha scritto il codice originale ma anche di chi si è dato tanto da fare per decodificarlo e per descriverne il funzionamento fin nei minimi particolari.&lt;/p&gt;&#xA;&lt;p&gt;Capire tutti i dettagli dell&amp;rsquo;articolo non è facile, ma  non credo che sia la cosa più importante. Ciò che importa è l&amp;rsquo;idea generale, è provare a mettersi nella testa di un programmatore per capire il suo modo di ragionare, è rendersi conto di quello che si può fare con una conoscenza più o meno approfondita di un linguaggio di programmazione (e delle basi matematiche che gli stanno dietro).&lt;/p&gt;&#xA;&lt;p&gt;Il nostro codice non sarà mai così elegante e compatto? Che importa, l&amp;rsquo;importante è iniziare a provarci. Tanto si può solo migliorare.&lt;/p&gt;&#xA;&lt;p&gt;Per la cronaca, questo è il codice finale dopo la decodifica.&lt;/p&gt;&#xA;&lt;p&gt;[code language=&amp;ldquo;javascript&amp;rdquo; ]&#xA;const DELAY = 64; // approximately 15 frames per second 15 frames per second * 64 seconds = 960 frames&#xA;var n = 1;&#xA;var p = document.getElementById(&amp;ldquo;p&amp;rdquo;);&#xA;// var draw = &amp;ldquo;for(n+=7,i=delay,P=&amp;lsquo;p.\n&amp;rsquo;;i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&amp;amp;1:2])j=delay/i;p.innerHTML=P&amp;rdquo;;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;/**&#xA; * Draws a picture&#xA; * 128 chars by 32 chars = total 4096 chars&#xA; */&#xA;var draw = function() {&#xA;    var i = DELAY; // 64&#xA;    var P =&#39;p.\n&#39;; // First line, reference for chars to use&#xA;    var j;&#xA; &#xA;    n += 7;&#xA; &#xA;    while (i &amp;gt; 0) {&#xA; &#xA;        j = DELAY / i;&#xA;        i -= 1 / DELAY;&#xA; &#xA;        let index;&#xA;        let iIsOdd = (i % 2 != 0);&#xA; &#xA;        if (iIsOdd) {&#xA;            let magic = ((i % 2 * j - j + n / DELAY) ^ j); // &amp;lt; ------------------&#xA;            let magicIsOdd = (magic % 2 != 0); // &amp;amp;1&#xA;            if (magicIsOdd) { // &amp;amp;1&#xA;                index = 1;&#xA;            } else {&#xA;                index = 0;&#xA;            }&#xA;        } else {&#xA;            index = 2;&#xA;        }&#xA; &#xA;        switch (index) { // P += P[index];&#xA;            case 0:&#xA;                P += &amp;quot;p&amp;quot;; // aka P[0]&#xA;                break;&#xA;            case 1:&#xA;                P += &amp;quot;.&amp;quot;; // aka P[1]&#xA;                break;&#xA;            case 2:&#xA;                P += &amp;quot;\n&amp;quot;; // aka P[2]&#xA;        }&#xA;    }&#xA;    //Update HTML&#xA;    p.innerHTML = P;&#xA;};&#xA; &#xA;setInterval(draw, 64);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;[/code]&lt;/p&gt;&#xA;&lt;p&gt;Incredibile, no?&lt;/p&gt;&#xA;&lt;p&gt;I più volonterosi possono anche &lt;a href=&#34;https://codepen.io/akras14/pen/qjgrxz&#34; target=&#34;_blank&#34;&gt;provare a giocare con il codice&lt;/a&gt;, modificandolo a loro piacimento. Si può ad esempio cambiare colore e dimensioni del testo, inserendo queste righe nella sezione CSS (e poi andando a &lt;a href=&#34;https://www.w3schools.com/css/css_syntax.asp&#34;&gt;leggere qui per capire perché&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#p {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;blue&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;font-size&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Oppure modificare le le strighe &lt;code&gt;&amp;quot;p&amp;quot;&lt;/code&gt; e &lt;code&gt;&amp;quot;.&amp;quot;&lt;/code&gt;, rispettivamente alle linee 39 e 42 del codice JavaScript, per cambiare i caratteri mostrati sullo schermo. Ancora più interessante è variare il valore di &lt;code&gt;DELAY&lt;/code&gt; nella prima riga del codice JavaScript e vedere l&amp;rsquo;effetto che fa.&lt;/p&gt;&#xA;&lt;p&gt;Sembra solo un giochetto un po&amp;rsquo; stupido, ma si impara a programmare (anche) così.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Emulare il Macintosh online (seconda parte)</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2017/05/07/emulare-il-macintosh-online-seconda-parte/</link>
      <pubDate>Sun, 07 May 2017 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2017/05/07/emulare-il-macintosh-online-seconda-parte/</guid>
      <description>&lt;p&gt;Nella &lt;a href=&#34;https://melabit.wordpress.com/2017/04/23/emulare-il-macintosh-online/&#34;&gt;puntata precedente&lt;/a&gt; abbiamo visto che da qualche settimana è disponibile un &lt;a href=&#34;https://archive.org/details/softwarelibrary_mac&#34;&gt;emulatore online del primo Macintosh&lt;/a&gt;, con il quale si possono provare parecchie applicazioni storiche per il Mac direttamente dal browser.&lt;/p&gt;&#xA;&lt;p&gt;Le applicazioni presenti in questo momento sono 77, non tantissime, ma è probabile che aumentino con il tempo.&lt;/p&gt;&#xA;&lt;p&gt;Ci sono due versioni di MacOS (proprio così, con Sierra siamo &lt;a href=&#34;https://www.apple.com/lae/macos/sierra/&#34;&gt;tornati allo stesso nome&lt;/a&gt; ma con una maiuscola in meno), un System 6 ridotto all&amp;rsquo;osso e un System 7 (del 1991) con un buon numero di applicazioni installate, a mostrare cosa poteva fare un Mac un quarto di secolo fa (System 7 è praticamente contemporaneo a &lt;a href=&#34;https://en.wikipedia.org/wiki/Windows_3.0&#34;&gt;Windows 3.0&lt;/a&gt;, uno dei sistemi operativi più inutili e pieni di bachi che abbia mai utilizzato).&lt;/p&gt;&#xA;&lt;p&gt;Ci sono poi un po&amp;rsquo; di giochi &lt;em&gt;classici&lt;/em&gt;, che continuamo a vedere riproposti ancora oggi in tutte le salse, con solo un vestito più carino. Non mancano le applicazioni di produttività personale e qualche numero delle prime riviste in formato elettronico (e-zine).&lt;/p&gt;&#xA;&lt;p&gt;Per lo sviluppo ci sono alcuni BASIC, ma c&amp;rsquo;è soprattutto &lt;a href=&#34;https://arstechnica.com/apple/2012/05/25-years-of-hypercard-the-missing-link-to-the-web/&#34;&gt;HyperCard&lt;/a&gt; (con qualche stack relativo) a dimostrare la genialità di un &lt;a href=&#34;https://archive.org/details/CC501_hypercard&#34;&gt;programma troppo avanzato&lt;/a&gt; per i suoi tempi.&lt;/p&gt;&#xA;&lt;p&gt;Insomma, con questo emulatore si possono provare parecchie cose interessanti, utili per mostrare ai più giovani le virtù (e i limiti) dei Mac degli anni &amp;lsquo;80 e &amp;lsquo;90, e che fanno respirare un soffio di nostalgia a chi &lt;em&gt;c&amp;rsquo;era già&lt;/em&gt; e quei Mac e quei sistemi operativi li ha usati davvero.&lt;/p&gt;&#xA;&lt;p&gt;Ma fra le tutte applicazioni disponibili, quella che mi ha incuriosito di più è stata &lt;a href=&#34;https://archive.org/details/mac_DataFlow&#34;&gt;DataFlow Version 0.0&lt;/a&gt; (attenzione al numero di versione).&lt;/p&gt;&#xA;&lt;p&gt;Non ne avevo mai sentito parlare, però non pretendo di certo di conoscere tutto il software sviluppato per il Mac (o per qualunque altra piattaforma). Forse quello che mi ha colpito è la finestra scarna e quasi vuota del programma, molto diversa rispetto a tutti gli altri programmi disponibili.&lt;/p&gt;&#xA;&lt;p&gt;Lancio l&amp;rsquo;emulatore e la prima impressione è che DataFlow sia un programma come tanti, qualcosa per realizzare diagrammi di flusso o simili.&lt;/p&gt;&#xA;&lt;p&gt;Ma poi guardo con più attenzione e mi accorgo che in realtà DataFlow è molto di più, è un sistema, anche se assai rudimentale, di programmazione visuale basato sul concetto di &lt;a href=&#34;https://en.wikipedia.org/wiki/Dataflow_programming&#34;&gt;programma a &lt;em&gt;flusso di dati&lt;/em&gt;&lt;/a&gt; (da cui il nome).&lt;/p&gt;&#xA;&lt;p&gt;In pratica un programma di questo tipo è composto da un certo numero di blocchi fondamentali che eseguono una operazione predefinita sui dati in ingresso e poi li trasmettono al blocco successivo. Poiché i blocchi di elaborazione sono indipendenti fra loro, questo semplice concetto porta naturalmente al calcolo parallelo, senza i trucchi e gli inganni di tanti linguaggi adattati in modo un po&amp;rsquo; raffazzonato allo scopo.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;idea era relativamente nuova per l&amp;rsquo;epoca (con DataFlow siamo più o meno alla fine degli anni &amp;lsquo;80) ma ha generato sistemi di programmazione molto avanzati, utilizzati ancora oggi in ambiti estremamente diversi. Come ad esempio &lt;a href=&#34;https://en.wikipedia.org/wiki/LabVIEW&#34;&gt;LabVIEW&lt;/a&gt; di National Instruments per il controllo della strumentazione elettronica, &lt;a href=&#34;https://it.mathworks.com/products/simulink.html&#34;&gt;Simulink&lt;/a&gt; di MathWorks per la modellazione di sistemi dinamici, &lt;a href=&#34;https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/QuartzComposerUserGuide/qc_intro/qc_intro.html&#34;&gt;Quartz Composer&lt;/a&gt; di Apple per la composizione grafica e, più recentemente, &lt;a href=&#34;https://www.tensorflow.org/&#34;&gt;TensorFlow&lt;/a&gt; di Google, diventato in pochissimo tempo uno degli strumenti più &lt;em&gt;popolari&lt;/em&gt;, anzi direi proprio &lt;em&gt;hot&lt;/em&gt;, nel campo della programmazione e dell&amp;rsquo;intelligenza artificiale.&lt;/p&gt;&#xA;&lt;p&gt;Insomma DataFlow è un anticipo del futuro, una vera chicca buttata lì con noncuranza fra un foglio elettronico ed un giochino senza tante pretese.&lt;/p&gt;&#xA;&lt;p&gt;Usarlo non è semplice, almeno per le abitudini odierne. L&amp;rsquo;interfaccia è rozza, i blocchi grafici non si possono spostare dopo averli posizionati sul foglio (io almeno non ci sono riuscito), le linee di connessione vanno un po&amp;rsquo; troppo per i fatti loro, si vede che è una versione molto acerba (versione 0.0, oggi la chiameremmo una versione &lt;em&gt;alfa&lt;/em&gt; se non meno). Alla fine comunque sono riuscito a fare un programmino semplice semplice, che prende due numeri interi e ne calcola somma, prodotto e quoziente.&lt;/p&gt;&#xA;&lt;img src=&#34;https://melabit.files.wordpress.com/2017/05/dataflow.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Niente di che, è chiaro, ma quello che è particolarmente bello è che il programma è &lt;em&gt;dinamico&lt;/em&gt;, se si cambiano i numeri in ingresso mentre il programma è in esecuzione le caselle di uscita aggiornano immediatamente i risultati. Oggi è scontato, ma trent&amp;rsquo;anni fa?&lt;/p&gt;&#xA;&lt;p&gt;Naturalmente i programmi moderni fanno molto di più e in modo molto più comodo, ma i fondamenti ci sono già tutti in DataFlow. È bello che l&amp;rsquo;Internet Archive l&amp;rsquo;abbia sottratto all&amp;rsquo;oblio del tempo.&lt;/p&gt;&#xA;&lt;img src=&#34;http://forums.ni.com/attachments/ni/250/29496/1/Example.JPG&#34; alt=&#34;&#34;&gt;&lt;p&gt;&lt;img src=&#34;http://blogs.mathworks.com/images/seth/2008Q1/vdp_PlayButton.png&#34; alt=&#34;&#34;&gt;&lt;br&gt;&#xA;&lt;em&gt;Un semplice programma in LabVIEW (sopra), e in una vecchia versione di Simulink (sotto).&lt;/em&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Regolarizziamo</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2017/02/20/regolarizziamo/</link>
      <pubDate>Mon, 20 Feb 2017 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2017/02/20/regolarizziamo/</guid>
      <description>&lt;img src=&#34;https://imgs.xkcd.com/comics/perl_problems.png&#34; alt=&#34;&#34;&gt;&lt;p&gt;Le espressioni regolari sono uno degli argomenti più ostici che ci si può trovare ad affrontare quando si usa un computer. Purtroppo sono anche una delle cose più utili, in particolare quando si cerca qualcosa che è sepolto nel disco rigido o quando si devono estrarre informazioni da grosse moli di dati.&lt;/p&gt;&#xA;&lt;p&gt;Ma prima di tutto, cos&amp;rsquo;è una &lt;em&gt;espressione regolare&lt;/em&gt;, o come si dice normalmente in gergo informatico, una &lt;em&gt;regexp&lt;/em&gt;?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definizione.&lt;/strong&gt; Una espressione regolare è una sequenza di caratteri che definisce uno schema di ricerca (&lt;em&gt;search pattern&lt;/em&gt;) di informazioni strutturate in modo più o meno preciso.&lt;/p&gt;&#xA;&lt;p&gt;Ecco, la chiave di tutto sta proprio nella espressione &amp;ldquo;&lt;em&gt;più o meno preciso&lt;/em&gt;&amp;rdquo;. Cercare una parola precisa in un file è piuttosto facile, molto meno facile è cercare tutte le possibili variazioni della stessa parola, oppure intere classi di parole.&lt;/p&gt;&#xA;&lt;p&gt;Arrivato a questo punto dovrei fare qualche esempio più o meno complicato di uso delle espressioni regolari per risolvere qualche problema &lt;em&gt;pratico&lt;/em&gt;, come scambiare il nome con il cognome in una lista di indirizzi, aggiungere &lt;code&gt;http://&lt;/code&gt;, o meglio &lt;code&gt;https://&lt;/code&gt;, a tutti gli indirizzi web presenti in un file, cercare i numeri degli ordini di acquisto di una azienda e trasformarli in un formato standardizzato.&lt;/p&gt;&#xA;&lt;p&gt;Ma non mi sogno nemmeno di farlo, scappereste quasi tutti a gambe levate. Perché le espressioni regolari si apprezzano solo quando servono &lt;em&gt;veramente&lt;/em&gt;, quando permettono di risparmiare tempo e fatica facendo svolgere al computer, invece che a noi, le noiose operazioni ripetitive per le quali è così portato.&lt;/p&gt;&#xA;&lt;h4 id=&#34;imparare-ad-usare-le-espressioni-regolari&#34;&gt;Imparare ad usare le espressioni regolari&lt;/h4&gt;&#xA;&lt;p&gt;E allora come si può imparare ad usare queste benedette espressioni regolari?&lt;/p&gt;&#xA;&lt;p&gt;Ci sono decine di libri e di tutorial che ne trattano, ne ho elencati alcuni nella bibliografia. Devo però ammettere che i libri e la maggior parte dei tutorial non li ho mai non dico letti ma nemmeno guardati, mi annoierebbero troppo con le loro sequenze di regole e regolette, terra-terra e quasi inutili o così acrobatiche da essere incomprensibili.&lt;/p&gt;&#xA;&lt;p&gt;Molto meglio i siti web che insegnano ad usare in pratica le espressioni regolari: inserisci da una parte l&amp;rsquo;espressione regolare e dall&amp;rsquo;altra il testo in cui cercare e l&amp;rsquo;applicazione mette in evidenza tutte le sequenze di caratteri che soddisfano l&amp;rsquo;espressione inserita (le &lt;em&gt;occorrenze&lt;/em&gt;), con una spiegazione più o meno dettagliata di quello che succede.&lt;/p&gt;&#xA;&lt;p&gt;Fra tutti i siti di questo tipo, il mio preferito è &lt;a href=&#34;https://regex101.com/&#34;&gt;regex101&lt;/a&gt;, veloce e con spiegazioni chiare e prive di inutili dettagli. Al secondo posto &lt;a href=&#34;https://www.debuggex.com/&#34;&gt;Debuggex&lt;/a&gt;, ottimo ma più complesso da usare, soprattutto le prime volte. Non male anche &lt;a href=&#34;http://regexr.com/&#34;&gt;RegExr&lt;/a&gt;, che però interpreta le espressioni regolari inserite utilizzando il motore JavaScript del browser, che non è sempre compatibile al 100% con le espressioni regolari di altri linguaggi.&lt;/p&gt;&#xA;&lt;h4 id=&#34;ci-sporchiamo-le-mani&#34;&gt;Ci sporchiamo le mani?&lt;/h4&gt;&#xA;&lt;p&gt;Tutto qui? Per ora si, questa voleva essere solo una piccolissima introduzione al mondo oggettivamente complicato delle espressioni regolari. Più o meno come mettere il dito nell&amp;rsquo;acqua per vedere se è fredda.&lt;/p&gt;&#xA;&lt;p&gt;Se l&amp;rsquo;argomento interessa, si può andare avanti con l&amp;rsquo;esplorazione, magari partendo da problemi pratici non troppo banali (affrontabili con tecniche meno complesse), ma nemmeno tanto complicati da risultare ostici.&lt;/p&gt;&#xA;&lt;p&gt;Che ne dite? Aspetto il vostro feedback nei commenti.&lt;/p&gt;&#xA;&lt;h4 id=&#34;bibliografia&#34;&gt;Bibliografia&lt;/h4&gt;&#xA;&lt;h5 id=&#34;libri&#34;&gt;Libri&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Fitzgerald, &lt;a href=&#34;http://shop.oreilly.com/product/0636920012337.do&#34;&gt;&lt;em&gt;Introducing Regular Expressions&lt;/em&gt;&lt;/a&gt; (O&amp;rsquo;Reilly 2012).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Goyvaerts, &lt;a href=&#34;http://shop.oreilly.com/product/0636920023630.do&#34;&gt;&lt;em&gt;Regular Expressions Cookbook&lt;/em&gt;&lt;/a&gt;, 2a edizione (O&amp;rsquo;Reilly 2012).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;López, Romero, &lt;a href=&#34;https://www.packtpub.com/application-development/mastering-python-regular-expressions&#34;&gt;&lt;em&gt;Mastering Python Regular Expressions&lt;/em&gt;&lt;/a&gt; (Packt 2014).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h5 id=&#34;tutorial&#34;&gt;Tutorial&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://regexone.com/&#34;&gt;RegexOne&lt;/a&gt;: learn regular expressions with simple, interactive exercises.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.regular-expressions.info/&#34;&gt;Regular-Expressions.info&lt;/a&gt;: the premier website about regular expressions.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.rexegg.com/&#34;&gt;Regex Tutorial&lt;/a&gt;: from regex 101 to advanced regex.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://blog.chalda.it/guida-alla-sintassi-delle-espressioni-regolari-217.html&#34;&gt;Guida alla sintassi delle espressioni regolari&lt;/a&gt; (con esempi).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.marioconcina.it/blog/come-fare/guida-alle-espressioni-regolari-regex.html&#34;&gt;Guida alle espressioni regolari (regex)&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.digitalocean.com/community/tutorials/using-grep-regular-expressions-to-search-for-text-patterns-in-linux&#34;&gt;Using Grep &amp;amp; Regular Expressions to Search for Text Patterns in Linux&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://matt.might.net/articles/sculpting-text/&#34;&gt;Sculpting text with regex, grep, sed, awk, emacs and vim&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h5 id=&#34;servizi-online&#34;&gt;Servizi online&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://regex101.com/&#34;&gt;regex101&lt;/a&gt;: an online regex tester and debugger.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.debuggex.com/&#34;&gt;Debuggex&lt;/a&gt;, an online visual regex tester.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://regexr.com/&#34;&gt;RegExr&lt;/a&gt;: learn, build, &amp;amp; test regex.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Compleanno con permessi</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2016/12/18/compleanno-con-permessi/</link>
      <pubDate>Sun, 18 Dec 2016 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2016/12/18/compleanno-con-permessi/</guid>
      <description>&lt;p&gt;Oggi &lt;a href=&#34;https://melabit.wordpress.com/&#34;&gt;melabit&lt;/a&gt; compie tre anni. Per l&amp;rsquo;occasione ho chiesto all&amp;rsquo;amico Lux il permesso di ripubblicare un mio vecchio intervento sul suo (bellissimo) blog &lt;a href=&#34;http://web.archive.org/web/20120102191652/http://www.macworld.it/ping&#34;&gt;Ping&lt;/a&gt;, chiuso purtroppo con la cessazione della pubblicazione dell&amp;rsquo;edizione italiana di Macworld.&lt;/p&gt;&#xA;&lt;p&gt;Perché pubblicare di nuovo questo articolo dopo più di sei anni?&lt;/p&gt;&#xA;&lt;p&gt;Innanzi tutto perché quello che c&amp;rsquo;è scritto è ancora attuale e, come ha scritto a suo tempo Lux con il suo stile inimitabile, può essere utile per &amp;ldquo;&lt;em&gt;avvicinarsi agli incantesimi Unix che danno vita al mondo magico di Mac OS X&lt;/em&gt;&amp;rdquo;, una cosa a cui tengo sempre moltissimo. Magari oggi &lt;a href=&#34;https://melabit.wordpress.com/2015/04/28/automatizzare-il-mac-dal-terminale-ancora-launchd/&#34;&gt;proporrei di usare sul Mac&lt;/a&gt; &lt;code&gt;launchd&lt;/code&gt; al posto di &lt;code&gt;cron&lt;/code&gt;, anche se quest&amp;rsquo;ultimo rimane la soluzione più generica, valida su un qualunque sistema Unix.&lt;/p&gt;&#xA;&lt;p&gt;C&amp;rsquo;è poi un motivo più personale: proprio dopo questo intervento ho cominciato a pensare che tenere un blog non fosse un&amp;rsquo;idea proprio fuori dal mondo. Ci ho messo un po&amp;rsquo; (come sempre!) a realizzarla, ma dopo tre anni devo ammettere che è stata un&amp;rsquo;ottima decisione, le soddisfazioni non sono mancate.&lt;/p&gt;&#xA;&lt;h4 id=&#34;introduzione&#34;&gt;Introduzione&lt;/h4&gt;&#xA;&lt;p&gt;L&amp;rsquo;articolo rispondeva all&amp;rsquo;esigenza di un lettore di Ping di cambiare automaticamente i permessi di determinati tipi di file contenuti in una cartella del Mac. Cosa ci può essere di meglio del Terminale per fare queste cose?&lt;/p&gt;&#xA;&lt;p&gt;Ho lasciato praticamente inalterato il testo originale, limitandomi a correggere alcune imprecisioni e ad aggiungere qualche dettaglio qui e là.&lt;/p&gt;&#xA;&lt;h4 id=&#34;me-li-do-io-i-permessi&#34;&gt;Me li do io i permessi&lt;/h4&gt;&#xA;&lt;p&gt;&lt;strong&gt;Premessa #1&lt;/strong&gt;: il Terminale in Mac OS X si trova in &lt;code&gt;Applicazioni &amp;amp;#062; Utility&lt;/code&gt;. Una volta lanciato può essere configurato in molti modi (tramite le Preferenze) perdendo quell’aspetto un po&amp;rsquo; triste e troppo serioso che spaventa l’utente normale.&lt;/p&gt;&#xA;&lt;p&gt;Dopo l&amp;rsquo;avvio, il Terminale presenta il cosiddetto &lt;em&gt;prompt&lt;/em&gt;, che su OS X mostra tipicamente il nome del computer, la cartella dove ci si trova e il nome dell’utente. L’ultimo carattere del prompt è normalmente il &lt;code&gt;$&lt;/code&gt;. Nel Terminale i comandi vengono inseriti dopo il simbolo &lt;code&gt;$&lt;/code&gt; su quella che viene definita la &lt;em&gt;riga di comando&lt;/em&gt; e si eseguono premendo il tasto &lt;code&gt;Invio&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Il Terminale di OS X esegue di default la cosiddetta &lt;a href=&#34;https://tiswww.case.edu/php/chet/bash/bashref.html#Introduction&#34;&gt;&lt;em&gt;shell&lt;/em&gt; &lt;code&gt;bash&lt;/code&gt;&lt;/a&gt;, uno strumento potentissimo per interagire con il sistema operativo. La shell &lt;code&gt;bash&lt;/code&gt; può essere usata direttamente, scrivendo i comandi uno ad uno sulla riga di comando e leggendone il risultato direttamente nel Terminale.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://melabit.files.wordpress.com/2016/12/terminal.png&#34;&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2016/12/terminal.png&#34; alt=&#34;Il Terminale di OS X&#34; class=&#34;aligncenter&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Oppure si possono scrivere degli &lt;code&gt;script&lt;/code&gt;, piccoli programmi nel linguaggio di &lt;code&gt;bash&lt;/code&gt; nei quali si inseriscono in sequenza i comandi da far eseguire alla shell, che si dimostrano molto utili per automatizzare delle operazioni che eseguiamo ripetutamente sul Mac.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Premessa #2&lt;/strong&gt;: perché usare i comandi di &lt;code&gt;bash&lt;/code&gt; invece di Automator o di AppleScript? Beh, innanzitutto perché &lt;code&gt;bash&lt;/code&gt; è multipiattaforma e quindi funziona su Linux e, volendo, anche su Windows. E poi semplicemente perché &lt;code&gt;bash&lt;/code&gt; mi piace!&lt;/p&gt;&#xA;&lt;p&gt;Lanciamo quindi il Terminale (magari configurandolo prima, io consiglio almeno di aumentare le dimensioni della finestra a circa 100×40 per stare comodi e di scegliere un tema grafico più accattivante di quello bianco e un po&amp;rsquo; spento di default) e iniziamo a lavorare.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://melabit.files.wordpress.com/2016/12/bash_profiles.png&#34;&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2016/12/bash_profiles.png&#34; alt=&#34;Configurazione di bash&#34; class=&#34;aligncenter&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Creiamo innanzi tutto una cartella &lt;code&gt;~/bin&lt;/code&gt;, dove il carattere &lt;code&gt;~&lt;/code&gt; (tilde, ALT+5) indica per convenzione sui sistemi basati su Unix la cartella &lt;code&gt;Inizio&lt;/code&gt; (detta anche &lt;code&gt;Home&lt;/code&gt;) dell’utente che sta usando il computer in questo momento. Per farlo da Terminale, digitiamo (ATTENZIONE, come già detto &lt;code&gt;$&lt;/code&gt; indica solo l’ultimo carattere del prompt e &lt;strong&gt;NON&lt;/strong&gt; va mai inserito nei comandi seguenti):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cd&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir bin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ chflags hidden bin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cd bin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il primo comando serve per essere sicuri di partire dalla &lt;code&gt;Home&lt;/code&gt;, il secondo crea una nuova cartella &lt;code&gt;bin&lt;/code&gt; nella &lt;code&gt;Home&lt;/code&gt;, il terzo la nasconde al Finder e l’ultimo comando ci fa spostare nella cartella &lt;code&gt;bin&lt;/code&gt; appena creata.&lt;/p&gt;&#xA;&lt;p&gt;In teoria siamo liberi di salvare i nostri comandi &lt;code&gt;bash&lt;/code&gt; in una qualunque cartella del Mac e possiamo anche usarne una già esistente. Ma usare la cartella &lt;code&gt;bin&lt;/code&gt; nella nostra &lt;code&gt;Home&lt;/code&gt; rispetta le convenzioni dei sistemi Unix e mi sembra preferibile.&lt;/p&gt;&#xA;&lt;p&gt;A questo punto usiamo &lt;code&gt;nano&lt;/code&gt; (un editor testuale molto semplice installato di default sul Mac) per editare lo &lt;em&gt;script&lt;/em&gt; &lt;code&gt;bash&lt;/code&gt; &lt;code&gt;cambia_permessi&lt;/code&gt;, nel quale inseriremo i comandi veri e propri che ci servono per cambiare i permessi dei file contenuti nella cartella nella quale verrà eseguito lo script:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nano cambia_permessi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Non preoccupatevi per l’interfaccia un po&amp;rsquo; ostica di &lt;code&gt;nano&lt;/code&gt;, qui ci basta usare solo due comandi, &lt;code&gt;CTRL+O&lt;/code&gt; per salvare il file editato e &lt;code&gt;CTRL+X&lt;/code&gt; per uscire da nano. Dimenticavo: &lt;code&gt;CTRL+O&lt;/code&gt; significa premere contemporaneamente il tasto &lt;code&gt;CTRL&lt;/code&gt;, l’ultimo in basso a sinistra sulle tastiere Mac (nei portatili è a fianco di fn), e il tasto &lt;code&gt;O&lt;/code&gt;. Analogamente per &lt;code&gt;CTRL+X&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Torniamo al nostro file &lt;code&gt;cambia_permessi&lt;/code&gt;. A questo punto bisognerebbe copiare a mano le linee mostrate qui sotto. Ma OS X è furbo e il copia e incolla funziona anche nella finestra del Terminale, per cui è sufficiente selezionare tutte le linee mostrate qui sotto, copiarle e poi incollarle nella finestra del Terminale dove è attivo &lt;code&gt;nano&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/bash&#xA;#&#xA;DIR=~/scansioni/&#xA;FILES=*&#xA;PERM=u+rw&#xA;#&#xA;if [ -d $DIR ]; then&#xA;&#x9;cd $DIR&#xA;&#x9;chmod -R $PERM $FILES&#xA;&#x9;cd&#xA;fi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Salviamo lo script premendo &lt;code&gt;CTRL+O&lt;/code&gt; ed usciamo da &lt;code&gt;nano&lt;/code&gt; con &lt;code&gt;CTRL+X&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Cosa significano questi comandi? Il più importante è &lt;code&gt;chmod&lt;/code&gt;, che cambia i permessi di tutti i file contenuti nella cartella ``~/scansioni/` in modo che siano leggibili e scrivibili dall&amp;rsquo;utente attuale del Mac. Il resto è solo roba di contorno.&lt;/p&gt;&#xA;&lt;p&gt;Quello che è ancora più importante è che lo script è totalmente parametrico: basta cambiare i valori di &lt;code&gt;DIR&lt;/code&gt;, &lt;code&gt;FILES&lt;/code&gt; e &lt;code&gt;PERM&lt;/code&gt; per adattarlo alle proprie esigenze.&lt;/p&gt;&#xA;&lt;p&gt;Per esempio, se la cartella &lt;code&gt;~/scansioni/&lt;/code&gt; contenesse vari tipi di file e si volessero cambiare i permessi dei soli file &lt;code&gt;pdf&lt;/code&gt; lasciando gli altri file invariati, la riga &lt;code&gt;FILES=*&lt;/code&gt; diventerebbe &lt;code&gt;FILES=*.pdf&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Non è finita. Controlliamo prima di tutto di avere veramente fatto tutto bene con il comando:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cat cambia_permessi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;che dovrebbe mostrare sullo schermo lo script appena inserito.&lt;/p&gt;&#xA;&lt;p&gt;Per semplificarci la vita, rendiamo lo script eseguibile con il comando:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ chmod u+x cambia_permessi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bisogna notare che con questo comando abbiamo reso eseguibile lo script solo per l’utente attuale del Mac. I motivi li tralascio per brevità, ma credetemi, è decisamente meglio fare così.&lt;/p&gt;&#xA;&lt;p&gt;Un ultimo passo necessario. In questo momento, per cambiare i permessi dei file nella cartella &lt;code&gt;~/scansioni/&lt;/code&gt; bisogna eseguire a mano il comando dal Terminale:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ~/bin/cambia_permessi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(anche se, per come è configurato di default OS X, usare soltanto &lt;code&gt;$ cambia_permessi&lt;/code&gt;, senza scrivere esplicitamente il percorso dove è salvato lo script basta e avanza).&lt;/p&gt;&#xA;&lt;p&gt;Ciò è sicuramente molto più comodo di cambiare uno ad uno i permessi dei file, ma si può fare di meglio.&lt;/p&gt;&#xA;&lt;p&gt;Qui entra in gioco &lt;code&gt;cron&lt;/code&gt;, uno strumento che esegue dei comandi stabiliti dall’utente a intervalli di tempo predefiniti. Sembra una cosa un po&amp;rsquo; cretina, ma in realtà permette di far fare al computer un mare di cose automaticamente. Purtoppo la sintassi di cron è orrenda. E questo post sta diventando troppo lungo.&lt;/p&gt;&#xA;&lt;p&gt;Cercherò di sintetizzare ma se qualcuno è interessato posso scrivere qualcosa in proposito. (Nel frattempo l&amp;rsquo;ho fatto, chi fosse interessato può leggere questo &lt;a href=&#34;https://melabit.wordpress.com/2014/11/22/automatizzare-il-mac-dal-terminale-sua-maesta-cron/&#34;&gt;articolo dettagliato su cron&lt;/a&gt;.)&lt;/p&gt;&#xA;&lt;p&gt;Diciamo che vogliamo che ogni cinque minuti lo script &lt;code&gt;cambia_permessi&lt;/code&gt; venga eseguito automaticamente. Dal solito Terminale dobbiamo allora eseguire i comandi:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ export EDITOR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/bin/nano&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ crontab -e&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La prima riga serve ad evitare di usare l’editor preimpostato, &lt;code&gt;vi&lt;/code&gt;, vn vero reperto archeologico che sarebbe bene dimenticare una volta per tutte. Dovrebbe invece aprirsi il solito &lt;code&gt;nano&lt;/code&gt;, in cui dobbiamo incollare &lt;strong&gt;esattamente&lt;/strong&gt; la riga seguente:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*/5 * * * * ~/bin/cambia_permessi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(prima e dopo ciascun asterisco è presente una tabulazione), eventualmente aggiungendola in coda ai comandi già presenti.&lt;/p&gt;&#xA;&lt;p&gt;Salviamo con &lt;code&gt;CTRL+O&lt;/code&gt; e usciamo da &lt;code&gt;crontab&lt;/code&gt; con &lt;code&gt;CTRL+X&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Ovviamente se vogliamo che lo script venga eseguito più o meno frequentemente, basta cambiare il valore &lt;code&gt;*/5&lt;/code&gt; in, diciamo, &lt;code&gt;*/2&lt;/code&gt; o &lt;code&gt;*/15&lt;/code&gt; (per eseguire lo script ogni 2 o 15 minuti). Per casi più complicati &lt;a href=&#34;https://melabit.wordpress.com/2014/11/22/automatizzare-il-mac-dal-terminale-sua-maesta-cron/&#34;&gt;basta leggere qui&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Abbiamo finito. Sembra complicato, ma credetemi, è molto più lungo da leggere (e da scrivere!) che da mettere in pratica.&lt;/p&gt;&#xA;&lt;h4 id=&#34;nota-finale&#34;&gt;Nota finale&lt;/h4&gt;&#xA;&lt;p&gt;Per chi ha paura del Terminale e soprattutto di &lt;code&gt;cron&lt;/code&gt;, un programma potente ma, bisogna ammetterlo, ben poco &lt;em&gt;user-friendly&lt;/em&gt;, ecco una soluzione aggiuntiva, farina di Lux.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Aggiungo solo una piccola nota per gli inesperti di Terminale che si scontrano con &lt;code&gt;cron&lt;/code&gt; (e, su Snow Leopard, con &lt;code&gt;launchd&lt;/code&gt;). Una scorciatoia artigianale consiste nel definire un evento ricorrente dentro iCal e, nelle informazioni relative, stabilire che in occasione dell’evento va eseguito uno script.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;Molto pratica se si ha bisogno di ripetere uno &lt;em&gt;script&lt;/em&gt; una o due volte al giorno al massimo, in tutti gli altri casi temo che finirebbe per riempire all&amp;rsquo;inverosimile il proprio Calendario, con conseguenze che francamente mi sfuggono.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Duecento</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2016/07/05/duecento/</link>
      <pubDate>Tue, 05 Jul 2016 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2016/07/05/duecento/</guid>
      <description>&lt;p&gt;Con il post di sabato scorso siamo arrivati a 200. Due anni e mezzo di melabit e duecento post, in media uno ogni quattro giorni e mezzo. Non male, se si considerano i tanti impegni di ogni giorno, che mi impediscono di dare una periodicità più serrata al blog.&lt;/p&gt;&#xA;&lt;p&gt;Poiché questo in fondo è un blog dedicato alla programmazione e ai sistemi operativi (anche se me ne dimentico spesso), invece di celebrare l&amp;rsquo;evento preferisco prendere la palla al balzo e descrivere alcuni semplici comandi di Terminale, che userò per fare una piccola analisi dei post scritti finora.&lt;/p&gt;&#xA;&lt;p&gt;Lancio il Terminale (chi segue con continuità il blog dovrebbe sapere come fare, per gli altri il Terminale si trova in Applicazioni &amp;gt; Utility) e mi sposto nella cartella (&lt;em&gt;directory&lt;/em&gt;) che contiene tutti i miei post,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cd ~/cartella/del/blog/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Per prima cosa voglio controllare di aver scritto veramente 200 post.&lt;/p&gt;&#xA;&lt;p&gt;Sin dall&amp;rsquo;inizio ho deciso di usare per i nomi dei file sorgenti dei post il formato &lt;code&gt;anno-mese-giorno-titolo-separato-da-trattini.md&lt;/code&gt;, dove &lt;code&gt;anno-mese-giorno&lt;/code&gt; indica la data di pubblicazione, ad esempio &lt;code&gt;2016-07-05&lt;/code&gt; per questo post, e &lt;code&gt;.md&lt;/code&gt; è l&amp;rsquo;estensione standard dei documenti scritti in &lt;a href=&#34;https://lwn.net/Articles/610884/&#34;&gt;Markdown&lt;/a&gt;, il linguaggio di formattazione per il web che uso per scrivere questi post. La cartella contiene altri file e cartelle, ma solo i post completi hanno il nome in questo formato. Per contare i post contenuti nella cartella mi basta quindi eseguire il comando,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls 20*.md | wc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;che con &lt;code&gt;ls&lt;/code&gt; (&lt;em&gt;list&lt;/em&gt;) elenca tutti i file il cui nome inizia con il secolo corrente e termina con il suffisso &lt;code&gt;.md&lt;/code&gt;. L&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt; viene inviato tramite il simbolo &lt;code&gt;|&lt;/code&gt; (&lt;em&gt;pipe&lt;/em&gt;) ad un ulteriore comando del Terminale (in realtà della shell &lt;code&gt;bash&lt;/code&gt;, ma oggi non voglio essere troppo pignolo), &lt;code&gt;wc&lt;/code&gt; (&lt;em&gt;word count&lt;/em&gt;), che conta il numero di linee, parole e caratteri (e volendo anche di byte) di un file o, come in questo caso, dell&amp;rsquo;output del comando precedente.&lt;/p&gt;&#xA;&lt;p&gt;La risposta del Terminale è&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;201     202    8704&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove il primo numero rappresenta il numero di linee dell&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt;, cioè il numero dei file elencati da &lt;code&gt;ls&lt;/code&gt;  che rispettano le specifiche stabilite dal comando (e di conseguenza il numero dei post).&lt;/p&gt;&#xA;&lt;p&gt;Il Terminale quindi mi dice che finora ho scritto 201 post. &lt;em&gt;201&lt;/em&gt;? Certo, i post sono 201 perché nella lista c&amp;rsquo;è anche &lt;em&gt;questo post&lt;/em&gt; (potrei fare in modo da non considerarlo, ma renderebbe tutto inutilmente più complicato).&lt;/p&gt;&#xA;&lt;p&gt;C&amp;rsquo;è però un dettaglio che non torna. Il secondo numero, 202, indica il numero di parole dell&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt;. Poichè, come già notato, il nome dei file è nel formato &lt;code&gt;anno-mese-giorno-titolo-separato-da-trattini.md&lt;/code&gt;, che per &lt;code&gt;wc&lt;/code&gt; equivale ad una parola singola, i primi due numeri restituiti da &lt;code&gt;wc&lt;/code&gt; dovrebbero essere identici. Se il Terminale indica che c&amp;rsquo;è una parola in più, significa che uno dei file contiene nel nome (per sbaglio) uno spazio al posto del trattino.&lt;/p&gt;&#xA;&lt;p&gt;Per cercare il file in questione, eseguo questa volta&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls 20*.md | grep &amp;quot; &amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;inviando l&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt; a &lt;code&gt;grep&lt;/code&gt;, uno dei tool più importanti del Terminale, che serve per cercare una o più stringhe di testo in un file. Normalmente la ricerca viene effettuata usando una &lt;a href=&#34;http://regexone.com/&#34;&gt;espressione regolare&lt;/a&gt;, ma in questo caso è più che sufficiente limitarsi a cercare la presenza di un semplice spazio nell&amp;rsquo;output di &lt;code&gt;ls&lt;/code&gt;. La risposta è,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ 2015-12-23-first-draft-la prova.md&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove manca effettivamente il trattino fra &amp;ldquo;la&amp;rdquo; e &amp;ldquo;prova&amp;rdquo;. Correggo subito, eseguo di nuovo&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ ls 20*.md | wc&#xA;     201     201    8704&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;e questa volta ottengo il risultato che mi aspetto.&lt;/p&gt;&#xA;&lt;p&gt;Ora che ci siamo &lt;em&gt;scaldati&lt;/em&gt;, proviamo qualcosa di più divertente. Voglio sapere quante parole in tutto ho scritto finora in questi famosi 200 post. Facile, basta sostituire ad &lt;code&gt;ls&lt;/code&gt; il comando &lt;code&gt;cat&lt;/code&gt; (&lt;em&gt;concatenate&lt;/em&gt;), che stampa sul Terminale il contenuto dei file indicati dopo il comando. Eseguendo&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cat 20*.md&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;non faccio altro che stampare sullo schermo uno dietro l&amp;rsquo;altro il contenuto di tutti i file dei post. La stampa dei file è velocissima, ma scrollando all&amp;rsquo;indietro nel Terminale si può verificare che ci sono veramente tutti. Se volessi potrei usare &lt;code&gt;less&lt;/code&gt;,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cat 20*.md | less&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;per stampare i file riempiendo una pagina alla volta del Terminale (e potendo anche tornare indietro). Ma non mi interessa, preferisco inviare l&amp;rsquo;output di &lt;code&gt;cat&lt;/code&gt; a &lt;code&gt;wc&lt;/code&gt;,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ cat 20*.md | wc&#xA;   10639  113141  836099&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;da cui risulta che i 200 (anzi 201) post scritti finora sono composti in tutto da 10639 linee (che equivalgono in pratica ai paragrafi, separati fra loro da un a capo) e da ben 113141 parole.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Ogni post è quindi composto in media da&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ echo &amp;quot;113183 / 200&amp;quot; | bc&#xA;565&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ben 565 parole.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Per calcolare la media ho usato &lt;code&gt;bc&lt;/code&gt;, la calcolatrice integrata nel Terminale, un oggetto poco conosciuto ma a volte molto comodo. Anche in questo caso ho utilizzato il &lt;em&gt;pipe&lt;/em&gt; (&lt;code&gt;|&lt;/code&gt;) per inviare alla calcolatrice l&amp;rsquo;outupt di &lt;code&gt;echo&lt;/code&gt;, il comando che stampa su schermo la stringa (o le stringhe) che lo segue. Volendo avrei anche potuto usare &lt;code&gt;bc&lt;/code&gt; in modo interattivo,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ bc&#xA;bc 1.06&#xA;Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.&#xA;...&#xA;113183 / 200&#xA;565&#xA;quit&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Il risultato non è precisissimo, ogni file dei post ha anche una intestazione che non compare su Wordpress e che contiene titolo, data, categoria e tag, e così via. E poi non bisogna dimenticare che c&amp;rsquo;è di mezzo anche questo 201-esimo post, che è già ben più lungo di 565 parole. Ma insomma, ad occhio dovremmo essere più o meno sulle 520-530 parole &lt;em&gt;effettive&lt;/em&gt; per post.&lt;/p&gt;&#xA;&lt;p&gt;Ma c&amp;rsquo;è modo di vedere quante parole ci sono in ciascuno dei post? Certo, basta racchiudere i comandi precedenti in un ciclo &lt;code&gt;for&lt;/code&gt;,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ for i in `ls 20*.md`; do echo $i; cat $i | wc -w; done&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;dove &lt;code&gt;i&lt;/code&gt; è l&amp;rsquo;indice del ciclo &lt;code&gt;for&lt;/code&gt;, a cui viene associato di volta in volta uno dei nomi di file stampati da &lt;code&gt;ls&lt;/code&gt;. Nel corpo del ciclo &lt;code&gt;do... done&lt;/code&gt;, per ogni valore di &lt;code&gt;$i&lt;/code&gt; (in bash, ogni volta che si &lt;em&gt;usa&lt;/em&gt; una variabile, le si antepone il &lt;code&gt;$&lt;/code&gt;), si stampa con &lt;code&gt;echo $i&lt;/code&gt; prima il valore della variabile (cioè il nome del file), poi si usa &lt;code&gt; cat $i | wc -w&lt;/code&gt; per stampare il contenuto del file e inviarlo al &lt;em&gt;contatore&lt;/em&gt; &lt;code&gt;wc&lt;/code&gt;. L&amp;rsquo;opzione &lt;code&gt;-w&lt;/code&gt; (&lt;em&gt;word&lt;/em&gt;) di &lt;code&gt;wc&lt;/code&gt; serve per contare solo le parole. Eseguendo il ciclo ottengo&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ for i in `ls 20*.md`; do echo $i; cat $i | wc -w; done&#xA;2013-12-18-il-migliore-spot.md&#xA;     238&#xA;2013-12-18-melabit-il-blog.md&#xA;     497&#xA;2013-12-19-una-pinta-di-tablet.md&#xA;     346&#xA;2013-12-20-la-dogana.md&#xA;     165&#xA;2013-12-21-rinominare-i-file-con-il-terminale.md&#xA;     669&#xA;...&#xA;2016-05-24-rapidweaver-7-in-anteprima.md&#xA;     729&#xA;2016-05-27-cartellino-rosso-su-facebook.md&#xA;    1385&#xA;2016-05-28-la-matematica-di-facebook.md&#xA;     356&#xA;2016-06-05-playlist-per-bora-bora-brian-boru.md&#xA;     278&#xA;2016-07-02-da-latex-a-word-e-ritorno.md&#xA;    2278&#xA;2016-07-05-duecento.md&#xA;     987&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Per analizzare i dati è più comodo salvare la lista su un file, facendo in modo che il titolo del post e il conteggio delle parole stiano sulla stessa linea.&lt;/p&gt;&#xA;&lt;p&gt;Facile, per salvare l&amp;rsquo;output di un comando di Terminale su un file si usa il simbolo &lt;code&gt;&amp;amp;#62;&lt;/code&gt; seguito dal nome del file (&lt;a href=&#34;https://www.freebsd.org/doc/it/books/unix-introduction/special-features-file-redir.html&#34;&gt;ricapitolando&lt;/a&gt;, il simbolo &lt;code&gt;|&lt;/code&gt; invia l&amp;rsquo;output di un comando ad un altro comando, mentre il simbolo &lt;code&gt;&amp;amp;#62;&lt;/code&gt; lo invia ad un file). Per stampare titolo e conteggio sulla stessa linea, è sufficiente aggiungere al comando &lt;code&gt;echo&lt;/code&gt; l&amp;rsquo;opzione &lt;code&gt;-n&lt;/code&gt; (&lt;em&gt;no newline&lt;/em&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Eseguendo il comando così modificato,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ for i in `ls 20*.md`; do echo -n $i; cat $i | wc -w; done &amp;amp;#62; ~/Desktop/words.dat&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;compare sul Desktop il file &lt;code&gt;words.dat&lt;/code&gt;, le cui prime 5 righe sono,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ head -5 ~/Desktop/words.dat&#xA;2013-12-18-il-migliore-spot.md     238&#xA;2013-12-18-melabit-il-blog.md     497&#xA;2013-12-19-una-pinta-di-tablet.md     346&#xA;2013-12-20-la-dogana.md     165&#xA;2013-12-21-rinominare-i-file-con-il-terminale.md     669&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;esattamente come richiesto. Partendo da questi dati, è facile calcolare la distribuzione del numero di post in funzione del numero di parole,&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://melabit.files.wordpress.com/2016/07/words.png&#34;&gt;&lt;img src=&#34;https://melabit.files.wordpress.com/2016/07/words.png&#34; alt=&#34;Distribuzione del numero di post in funzione del numero di parole&#34; width=&#34;600&#34; height=&#34;432&#34; class=&#34;aligncenter size-full wp-image-2645&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;da cui è evidente che quasi la metà dei post contiene non più di 300 parole.&lt;/p&gt;&#xA;&lt;p&gt;Più specificatamente, si trova che la mediana è uguale a 346, che significa che metà dei post contiene meno di 346 parole e l&amp;rsquo;altra metà ne contiene di più. Forse non sono poi così prolisso come ho sempre pensato.&lt;/p&gt;&#xA;&lt;p&gt;Domanda (facoltativa): Perché c&amp;rsquo;è questa grossa differenza fra la media e la mediana del numero di parole che compongono i miei post?&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Si noti che se l&amp;rsquo;output di un comando che stampa qualcosa sul Terminale viene inviato ad un altro comando per un&amp;rsquo;ulteriore elaborazione, l&amp;rsquo;output stesso viene &lt;em&gt;risucchiato&lt;/em&gt; dal secondo comando e non compare più sullo schermo.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Forse sono troppo prolisso, 565 equivalgono a più di una pagina (densa) di un libro di formato medio-grande.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Input, un font per programmare</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2016/03/24/input-un-font-per-programmare/</link>
      <pubDate>Thu, 24 Mar 2016 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2016/03/24/input-un-font-per-programmare/</guid>
      <description>&lt;img src=&#34;https://melabit.files.wordpress.com/2016/03/input.png?w=300&#34; alt=&#34;input&#34; width=&#34;300&#34; height=&#34;267&#34; class=&#34;aligncenter size-medium wp-image-2405&#34; /&gt;&#xA;&lt;p&gt;Di font non capisco niente, distinguo a malapena Arial da Times Roman. Ho provato a leggere gli articoli di Nick Keppol su San Francisco, il nuovo font di sistema di Apple Watch e delle versioni più recenti di OS X e iOS (sia la &lt;a href=&#34;http://martiancraft.com/blog/2015/10/why-san-francisco/&#34;&gt;prima&lt;/a&gt; che la &lt;a href=&#34;http://martiancraft.com/blog/2015/10/san-francisco-part-2/&#34;&gt;seconda&lt;/a&gt; parte), ma ammetto di averci capito ben poco.&lt;/p&gt;&#xA;&lt;p&gt;Ammetto anche di non riuscire a cogliere appieno il legame fra la leggibilità di un font e le sue caratteristiche tecniche. Per fortuna non faccio il grafico, e quindi va benissimo così.&lt;/p&gt;&#xA;&lt;p&gt;Però la letture delgli articoli di Nick Keppol mi è stata utilissima lo stesso, perché mi ha fatto scoprire, &lt;a href=&#34;http://input.fontbureau.com/&#34;&gt;Input&lt;/a&gt;, un font monospaziato gratuito, particolarmente adatto non solo per chi programma, ma anche per tutti coloro che preferiscono scrivere con un editor, magari perché usano LaTeX o Markdown.&lt;/p&gt;&#xA;&lt;p&gt;Io ormai lo uso sempre più spesso, alternandolo ai miei font preferiti, Menlo, &lt;a href=&#34;https://en.wikipedia.org/wiki/Consolas&#34;&gt;Consolas&lt;/a&gt; e soprattutto &lt;a href=&#34;http://www.levien.com/type/myfonts/inconsolata.html&#34;&gt;Inconsolata&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Il bello di Input è che, prima di scaricarlo, può essere &lt;a href=&#34;http://input.fontbureau.com/preview/?size=14&amp;amp;language=python&amp;amp;theme=solarized-dark&amp;amp;family=InputSans&amp;amp;width=300&amp;amp;weight=300&amp;amp;line-height=1.2&amp;amp;a=0&amp;amp;g=0&amp;amp;i=0&amp;amp;l=0&amp;amp;zero=0&amp;amp;asterisk=0&amp;amp;braces=0&amp;amp;preset=default&amp;amp;customize=please&#34;&gt;configurato a piacere&lt;/a&gt;. Alcune opzioni mi sembrano particolarmente utili, come la possibilità di definire la forma della &amp;ldquo;l&amp;rdquo; (odio la l che si confonde con la i), dello zero o delle parentesi graffe, con l&amp;rsquo;anteprima immediata del risultato direttamente nel browser.&lt;/p&gt;&#xA;&lt;p&gt;Decisamente consigliato!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Due anni</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2015/12/18/due-anni/</link>
      <pubDate>Fri, 18 Dec 2015 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2015/12/18/due-anni/</guid>
      <description>&lt;img src=&#34;https://upload.wikimedia.org/wikipedia/commons/2/29/Wikidata_cupcake_II.svg&#34; alt=&#34;Due anni&#34; class=&#34;aligncenter&#34; width=&#34;256&#34; height=&#34;362&#34; /&gt;&#xA;&lt;p&gt;Oggi il blog festeggia il &lt;a href=&#34;https://melabit.wordpress.com/2013/12/18/melabit-il-blog/&#34;&gt;secondo compleanno&lt;/a&gt;. Sono riuscito a ricordarmene, anche se purtroppo negli ultimi mesi ho avuto veramente poco tempo da dedicarvi.&lt;/p&gt;&#xA;&lt;p&gt;Mi fa molto piacere che quest&amp;rsquo;anno il numero degli accessi sia raddoppiato rispetto al 2014 e che si mantenga abbastanza costante nel corso delle settimane e dei mesi. Significa che gli articoli durano nel tempo e vengono letti anche dopo parecchi mesi dalla pubblicazione.&lt;/p&gt;&#xA;&lt;p&gt;La metà dei visitatori è costituita da lettori fedeli, che ricevono gli aggiornamenti via email o visitano il blog periodicamente. Li ringrazio tutti per l&amp;rsquo;attenzione e la pazienza, a volte la pubblicazione dei nuovi post è veramente troppo aleatoria.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;altra metà ci arriva tramite i motori di ricerca. Praticamente solo &lt;a href=&#34;https://www.google.com&#34;&gt;Google&lt;/a&gt;, ma ci sono anche una ventina di accessi rispettivamente da &lt;a href=&#34;https://www.bing.com&#34;&gt;Bing&lt;/a&gt; o &lt;a href=&#34;https://search.yahoo.com&#34;&gt;Yahoo&lt;/a&gt; e perfino qualcuno che ha usato &lt;a href=&#34;http://arianna.libero.it&#34;&gt;Libero&lt;/a&gt;, &lt;a href=&#34;http://www.virgilio.it&#34;&gt;Virgilio&lt;/a&gt; o &lt;a href=&#34;https://duckduckgo.com&#34;&gt;DuckDuckGo&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Anche la distribuzione geografica degli accessi è piuttosto interessante. Come è ovvio la stragrande maggioranza proviene dall&amp;rsquo;Italia e dalla Svizzera (italiana?), ma ci sono centinaia di visite dagli USA e dai principali paesi europei, nell&amp;rsquo;ordine Regno Unito, Francia, Germania e Spagna.&lt;/p&gt;&#xA;&lt;p&gt;Ci sono comunque visitatori da quasi tutto il mondo. Mancano solo i paesi dell&amp;rsquo;Africa centrale, il Medio Oriente e la Cina. Quasi un miliardo e mezzo di abitanti ma nessun cinese interessato al blog, forse mi devo preoccupare. ;)&lt;/p&gt;&#xA;&lt;p&gt;[caption id=&amp;ldquo;attachment_2277&amp;rdquo; align=&amp;ldquo;aligncenter&amp;rdquo; width=&amp;ldquo;605&amp;rdquo;]&lt;img src=&#34;https://melabit.files.wordpress.com/2015/12/distribuzione_geografica.png?w=605&#34; alt=&#34;Distribuzione geografica degli accessi al blog nel 2015.&#34; width=&#34;605&#34; height=&#34;437&#34; class=&#34;size-large wp-image-2277&#34; /&gt; Distribuzione geografica degli accessi al blog nel 2015.[/caption]&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Non trovo le parole</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2015/12/04/non-trovo-le-parole/</link>
      <pubDate>Fri, 04 Dec 2015 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2015/12/04/non-trovo-le-parole/</guid>
      <description>&lt;p&gt;Non trovo le parole per descrivere al meglio &lt;a href=&#34;https://c1.goote.ch/c8a05c9a6d4a4929a3fa50e6ebdee0c3.scene/&#34;&gt;questo sito&lt;/a&gt; (e la &lt;a href=&#34;http://goocreate.com/product/&#34;&gt;tecnologia che c&amp;rsquo;è dietro&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Le animazioni sono realistiche, lo scroll velocissimo e naturale, tutto succede nel browser senza pause o impuntature. Perfino la musica, anche se ripetitiva, è affascinante.&lt;/p&gt;&#xA;&lt;p&gt;Altro che Flash, qui si dimostra al meglio la potenza e la flessibilità dell&amp;rsquo;HTML5. Questo è il futuro.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Programmare l&#39;inutilità</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2015/11/23/programmare-linutilita/</link>
      <pubDate>Mon, 23 Nov 2015 06:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2015/11/23/programmare-linutilita/</guid>
      <description>&lt;p&gt;Come tanti ricevo ogni giorno una o più email che mi propongono di visitare questo o quel sito. Non è sempre tempo perso, spesso si trovano delle vere e proprie gemme.&lt;/p&gt;&#xA;&lt;p&gt;Altre volte però scopro siti o applicazioni la cui utilità è perlomeno dubbia.&lt;/p&gt;&#xA;&lt;h4 id=&#34;img2css&#34;&gt;img2css&lt;/h4&gt;&#xA;&lt;p&gt;La palma del programma più inutile degli ultimi mesi vorrei assegnarla a &lt;a href=&#34;http://javier.xyz/img2css/&#34;&gt;img2css&lt;/a&gt;, una applicazione web scritta in JavaScript che converte una immagine bitmap (in formato png, jpg o simili) in un file CSS, che può qundi essere inserito direttamente in una pagina web.&lt;/p&gt;&#xA;&lt;p&gt;In teoria l&amp;rsquo;idea è ottima, perché permette di integrare un&amp;rsquo;immagine in una pagina web senza bisogno di collegamenti a file esterni, ma nella pratica fallisce miseramente.&lt;/p&gt;&#xA;&lt;p&gt;Anche con immagini semplicissime il file CSS generato diventa di dimensioni abnormi, ed è molto più pesante da gestire e da trasmettere in rete rispetto all&amp;rsquo;immagine originale.&lt;/p&gt;&#xA;&lt;h4 id=&#34;proviamo-img2css&#34;&gt;Proviamo img2css&lt;/h4&gt;&#xA;&lt;p&gt;Proviamo ad usare img2css con una immagine semplicissima composta da un quadrato di 10x10 pixel con bordo nero e interno bianco. L&amp;rsquo;immagine si può creare da Terminale tramite &lt;code&gt;convert&lt;/code&gt;, uno dei comandi più potenti di &lt;a href=&#34;http://www.imagemagick.org/script/index.php&#34;&gt;ImageMagick&lt;/a&gt;, in grado non solo (come dice il nome) di convertire le immagini da un formato grafico all&amp;rsquo;altro, ma anche di generare  delle immagini &lt;em&gt;ex-novo&lt;/em&gt; in praticamente qualunque formato conosciuto.&lt;/p&gt;&#xA;&lt;p&gt;Il comando&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;$ convert -size 10x10 xc:white -fill white &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;&#x9;-stroke black -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 0,0 9,9&amp;#34;&lt;/span&gt; square_10x10.png&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;produce l&amp;rsquo;immagine &lt;img src=&#34;https://melabit.files.wordpress.com/2015/11/square_10x10.png&#34; alt=&#34;square_10x10&#34; width=&#34;20&#34; height=&#34;20&#34; class=&#34;wp-image-2226&#34; /&gt;, che occupa esattamente 127 byte (per maggiore chiarezza l&amp;rsquo;immagine è visualizzata al doppio della dimensione originale).&lt;/p&gt;&#xA;&lt;p&gt;Convertendo l&amp;rsquo;immagine con &lt;code&gt;img2css&lt;/code&gt;, il codice CSS corrispondente&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;height:1px;width:1px;box-shadow:#000 0 0, #000 1px 0, #000 2px 0, #000 3px 0, #000 4px 0, #000 5px 0, #000 6px 0, #000 7px 0, #000 8px 0, #000 9px 0, #000 0 1px, #000 1px 1px, #000 2px 1px, #000 3px 1px, #000 4px 1px, #000 5px 1px, #000 6px 1px, #000 7px 1px, #000 8px 1px, #000 9px 1px, #000 0 2px, #000 1px 2px, #fff 2px 2px, #fff 3px 2px, #fff 4px 2px, #fff 5px 2px, #fff 6px 2px, #fff 7px 2px, #000 8px 2px, #000 9px 2px, #000 0 3px, #000 1px 3px, #fff 2px 3px, #fff 3px 3px, #fff 4px 3px, #fff 5px 3px, #fff 6px 3px, #fff 7px 3px, #000 8px 3px, #000 9px 3px, #000 0 4px, #000 1px 4px, #fff 2px 4px, #fff 3px 4px, #fff 4px 4px, #fff 5px 4px, #fff 6px 4px, #fff 7px 4px, #000 8px 4px, #000 9px 4px, #000 0 5px, #000 1px 5px, #fff 2px 5px, #fff 3px 5px, #fff 4px 5px, #fff 5px 5px, #fff 6px 5px, #fff 7px 5px, #000 8px 5px, #000 9px 5px, #000 0 6px, #000 1px 6px, #fff 2px 6px, #fff 3px 6px, #fff 4px 6px, #fff 5px 6px, #fff 6px 6px, #fff 7px 6px, #000 8px 6px, #000 9px 6px, #000 0 7px, #000 1px 7px, #fff 2px 7px, #fff 3px 7px, #fff 4px 7px, #fff 5px 7px, #fff 6px 7px, #fff 7px 7px, #000 8px 7px, #000 9px 7px, #000 0 8px, #000 1px 8px, #000 2px 8px, #000 3px 8px, #000 4px 8px, #000 5px 8px, #000 6px 8px, #000 7px 8px, #000 8px 8px, #000 9px 8px, #000 0 9px, #000 1px 9px, #000 2px 9px, #000 3px 9px, #000 4px 9px, #000 5px 9px, #000 6px 9px, #000 7px 9px, #000 8px 9px, #000 9px 9px;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;occupa 1259 byte, circa 10 volte in più del file &lt;code&gt;png&lt;/code&gt; di partenza. Le cose peggiorano rapidamente se si usano immagini più complesse. Questa immagine da 20x20 pixel &lt;img src=&#34;https://melabit.files.wordpress.com/2015/11/concentric_color.png&#34; alt=&#34;concentric_color&#34; width=&#34;20&#34; height=&#34;20&#34; class=&#34;wp-image-2232&#34; /&gt;, composta da alcuni rettangoli concentrici colorati e generata tramite&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ convert -size 20x20 xc:white -fill white &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-stroke black  -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 0,0 19,19&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-stroke red    -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 2,2 17,17&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-stroke green  -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 4,4 15,15&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-stroke blue   -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 6,6 13,13&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-stroke yellow -draw &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rectangle 8,8 11,11&amp;#34;&lt;/span&gt; concentric_color.png&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;occupa solo 481 byte in formato &lt;code&gt;png&lt;/code&gt;, che diventano ben 6.491 byte quando di converte l&amp;rsquo;immagine in CSS con &lt;code&gt;img2css&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Con immagini &lt;em&gt;reali&lt;/em&gt; a colori, o peggio ancora fotografie (&lt;a href=&#34;https://melabit.files.wordpress.com/2015/11/ipadpro.jpg&#34;&gt;ad esempio questa&lt;/a&gt;), le immagini CSS possono diventare anche 150-200 volte più grandi di quella originale, mettendo in ginocchio il browser (e il computer!) durante il processo di conversione o quando si copia il file CSS ottenuto in una pagina web.&lt;/p&gt;&#xA;&lt;p&gt;Provare per credere, ma se poi il Mac si pianta non prendetevela con me.&lt;/p&gt;&#xA;&lt;h4 id=&#34;dentro-il-codice&#34;&gt;Dentro il codice&lt;/h4&gt;&#xA;&lt;p&gt;Il programma &lt;a href=&#34;http://javier.xyz/img2css/&#34;&gt;img2css&lt;/a&gt; è molto semplice ed è composto poche centinaia di linee di codice JavaScript. Ma è perfino troppo lungo per quello che fa.&lt;/p&gt;&#xA;&lt;p&gt;In fondo si tratta solo di determinare il &lt;a href=&#34;http://www.rapidtables.com/web/color/RGB_Color.htm&#34;&gt;codice RGB&lt;/a&gt; di ogni pixel dell&amp;rsquo;immagine, convertirlo in &lt;a href=&#34;http://it.wikihow.com/Convertire-un-Numero-Decimale-in-Esadecimale&#34;&gt;formato esadecimale&lt;/a&gt; ed associarlo alle coordinate orizzonantali e verticali del pixel considerato.&lt;/p&gt;&#xA;&lt;p&gt;Ogni pixel viene quindi convertito nella sequenza &lt;code&gt;#AAA Xpx Ypx&lt;/code&gt;, dove &lt;code&gt;#AAA&lt;/code&gt; indica il colore in esadecimale (la stringa può essere composta da 3 o 6 numeri a seconda del colore RGB determinato) e &lt;code&gt;Xpx Ypx&lt;/code&gt; indicano le coordinate orizzonantali e verticali del pixel.&lt;/p&gt;&#xA;&lt;p&gt;Tutto questo si può fare tranquillamente da Terminale, con poche righe di codice ben piazzate.&lt;/p&gt;&#xA;&lt;h4 id=&#34;img2css-da-terminale&#34;&gt;img2css da Terminale&lt;/h4&gt;&#xA;&lt;p&gt;Per convertire un file grafico in una sequenza di colori RGB si può usare ancora &lt;code&gt;convert&lt;/code&gt; di &lt;a href=&#34;http://www.imagemagick.org/script/index.php&#34;&gt;ImageMagick&lt;/a&gt;,&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;$ convert square_10x10.png -compress none square_10x10.ppm&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;ottenendo un file in &lt;a href=&#34;http://netpbm.sourceforge.net/doc/ppm.html&#34;&gt;formato ppm&lt;/a&gt;, in cui ciascun pixel dell&amp;rsquo;immagine è rappresentato da tre numeri interi decimali, corrispondenti ai tre colori RGB del pixel stesso (il formato grafico &lt;code&gt;ppm&lt;/code&gt; è molto inefficiente, ma è utilissimo dal punto di vista didattico perché mostra chiaramente come è &lt;em&gt;fatto&lt;/em&gt; un file grafico).&lt;/p&gt;&#xA;&lt;p&gt;Le sequenze di tre  numeri decimali sono disposte per righe orizzontali a partire dalla quarta riga del file. Le prime tre righe contengono rispettivamente il &lt;em&gt;numero magico&lt;/em&gt; che definisce il tipo di file, le dimensioni dell&amp;rsquo;immagine in pixel e il valore massimo del colore RGB del file.&lt;/p&gt;&#xA;&lt;p&gt;La rappresentazione in formato &lt;code&gt;ppm&lt;/code&gt; del quadrato di 10x10 pixel con bordo nero e interno bianco &lt;img src=&#34;./file/img2css/square_10x10.png&#34; alt=&#34;&#34;&gt; mostrato sopra è&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;P3&#xA;10 10&#xA;255&#xA;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#xA;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sequenze di dati come questa possono essere facilmente analizzate e trasformate tramite &lt;a href=&#34;http://www.grymoire.com/Unix/Awk.html&#34;&gt;awk&lt;/a&gt;, uno dei tanti potenti strumenti specifici disponibili nei sistemi operativi basati su Unix.&lt;/p&gt;&#xA;&lt;p&gt;Basta uno script &lt;code&gt;awk&lt;/code&gt; di poche righe per convertire le informazioni RGB decimali contenute nel file &lt;code&gt;ppm&lt;/code&gt; in formato esadecimale&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/bin/awk -f&#xA;&#xA;/^255/  { while (getline == 1)&#xA;          { for (i = 1; i &amp;lt;= NF; i += 3)&#xA;              printf &amp;#34;0x%02X%02X%02X &amp;#34;, $i, $(i+1), $(i+2);&#xA;              printf &amp;#34;\n&amp;#34;&#xA;          }&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Eseguendo lo script &lt;code&gt;img2css.awk&lt;/code&gt; sul file &lt;code&gt;ppm&lt;/code&gt; precedente si ottiene&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./img2css.awk square_10x10.ppm &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 0x000000 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Per riprodurre l&amp;rsquo;output prodotto da &lt;code&gt;img2css&lt;/code&gt;, è sufficiente modificare leggermente il modo in cui lo script stampa i valori dei colori RGB, aggiungere la stampa della le coordinate di ciascun pixel e inserire le parti iniziali e finali del &lt;a href=&#34;http://www.w3schools.com/cssref/css3_pr_box-shadow.asp&#34;&gt;tag &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/a&gt;, ottenendo&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/bin/awk -f&#xA;&#xA;BEGIN   { out = sprintf(&amp;#34;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&amp;#34;);&#xA;          print out;&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;che produce un output equivalente a quello di img2css&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./img2css_v2.awk square_10x10.ppm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;div style&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;height:1px;width:1px;box-shadow:#000000 0 0px, #000000 1px 0px, #000000 2px 0px, #000000 3px 0px, #000000 4px 0px, #000000 5px 0px, #000000 6px 0px, #000000 7px 0px, #000000 8px 0px, #000000 9px 0px, #000000 0 1px, #000000 1px 1px, #000000 2px 1px, #000000 3px 1px, #000000 4px 1px, #000000 5px 1px, #000000 6px 1px, #000000 7px 1px, #000000 8px 1px, #000000 9px 1px, #000000 0 2px, #000000 1px 2px, #FFFFFF 2px 2px, #FFFFFF 3px 2px, #FFFFFF 4px 2px, #FFFFFF 5px 2px, #FFFFFF 6px 2px, #FFFFFF 7px 2px, #000000 8px 2px, #000000 9px 2px, #000000 0 3px, #000000 1px 3px, #FFFFFF 2px 3px, #FFFFFF 3px 3px, #FFFFFF 4px 3px, #FFFFFF 5px 3px, #FFFFFF 6px 3px, #FFFFFF 7px 3px, #000000 8px 3px, #000000 9px 3px, #000000 0 4px, #000000 1px 4px, #FFFFFF 2px 4px, #FFFFFF 3px 4px, #FFFFFF 4px 4px, #FFFFFF 5px 4px, #FFFFFF 6px 4px, #FFFFFF 7px 4px, #000000 8px 4px, #000000 9px 4px, #000000 0 5px, #000000 1px 5px, #FFFFFF 2px 5px, #FFFFFF 3px 5px, #FFFFFF 4px 5px, #FFFFFF 5px 5px, #FFFFFF 6px 5px, #FFFFFF 7px 5px, #000000 8px 5px, #000000 9px 5px, #000000 0 6px, #000000 1px 6px, #FFFFFF 2px 6px, #FFFFFF 3px 6px, #FFFFFF 4px 6px, #FFFFFF 5px 6px, #FFFFFF 6px 6px, #FFFFFF 7px 6px, #000000 8px 6px, #000000 9px 6px, #000000 0 7px, #000000 1px 7px, #FFFFFF 2px 7px, #FFFFFF 3px 7px, #FFFFFF 4px 7px, #FFFFFF 5px 7px, #FFFFFF 6px 7px, #FFFFFF 7px 7px, #000000 8px 7px, #000000 9px 7px, #000000 0 8px, #000000 1px 8px, #000000 2px 8px, #000000 3px 8px, #000000 4px 8px, #000000 5px 8px, #000000 6px 8px, #000000 7px 8px, #000000 8px 8px, #000000 9px 8px, #000000 0 9px, #000000 1px 9px, #000000 2px 9px, #000000 3px 9px, #000000 4px 9px, #000000 5px 9px, #000000 6px 9px, #000000 7px 9px, #000000 8px 9px, #000000 9px 9px;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/div&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;perfettamente funzionante, come si può verificare inserendo pari pari il tag &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; ottenuto in un documento html (come questo):&lt;/p&gt;&#xA;&lt;div style=&#34;height:1px;width:1px;box-shadow:#000000 0 0px, #000000 1px 0px, #000000 2px 0px, #000000 3px 0px, #000000 4px 0px, #000000 5px 0px, #000000 6px 0px, #000000 7px 0px, #000000 8px 0px, #000000 9px 0px, #000000 0 1px, #000000 1px 1px, #000000 2px 1px, #000000 3px 1px, #000000 4px 1px, #000000 5px 1px, #000000 6px 1px, #000000 7px 1px, #000000 8px 1px, #000000 9px 1px, #000000 0 2px, #000000 1px 2px, #FFFFFF 2px 2px, #FFFFFF 3px 2px, #FFFFFF 4px 2px, #FFFFFF 5px 2px, #FFFFFF 6px 2px, #FFFFFF 7px 2px, #000000 8px 2px, #000000 9px 2px, #000000 0 3px, #000000 1px 3px, #FFFFFF 2px 3px, #FFFFFF 3px 3px, #FFFFFF 4px 3px, #FFFFFF 5px 3px, #FFFFFF 6px 3px, #FFFFFF 7px 3px, #000000 8px 3px, #000000 9px 3px, #000000 0 4px, #000000 1px 4px, #FFFFFF 2px 4px, #FFFFFF 3px 4px, #FFFFFF 4px 4px, #FFFFFF 5px 4px, #FFFFFF 6px 4px, #FFFFFF 7px 4px, #000000 8px 4px, #000000 9px 4px, #000000 0 5px, #000000 1px 5px, #FFFFFF 2px 5px, #FFFFFF 3px 5px, #FFFFFF 4px 5px, #FFFFFF 5px 5px, #FFFFFF 6px 5px, #FFFFFF 7px 5px, #000000 8px 5px, #000000 9px 5px, #000000 0 6px, #000000 1px 6px, #FFFFFF 2px 6px, #FFFFFF 3px 6px, #FFFFFF 4px 6px, #FFFFFF 5px 6px, #FFFFFF 6px 6px, #FFFFFF 7px 6px, #000000 8px 6px, #000000 9px 6px, #000000 0 7px, #000000 1px 7px, #FFFFFF 2px 7px, #FFFFFF 3px 7px, #FFFFFF 4px 7px, #FFFFFF 5px 7px, #FFFFFF 6px 7px, #FFFFFF 7px 7px, #000000 8px 7px, #000000 9px 7px, #000000 0 8px, #000000 1px 8px, #000000 2px 8px, #000000 3px 8px, #000000 4px 8px, #000000 5px 8px, #000000 6px 8px, #000000 7px 8px, #000000 8px 8px, #000000 9px 8px, #000000 0 9px, #000000 1px 9px, #000000 2px 9px, #000000 3px 9px, #000000 4px 9px, #000000 5px 9px, #000000 6px 9px, #000000 7px 9px, #000000 8px 9px, #000000 9px 9px;&#34;&gt;&lt;/div&gt;&#xA;&lt;h4 id=&#34;conclusioni&#34;&gt;Conclusioni&lt;/h4&gt;&#xA;&lt;p&gt;È chiaro che usare &lt;code&gt;convert&lt;/code&gt; ed &lt;code&gt;awk&lt;/code&gt; non risolve il problema di fondo, le immagini CSS generate rimangono comunque molto più grosse di quelle originali, ma almeno sono prodotte con poche righe di codice ed usando solo degli strumenti standard di Unix.&lt;/p&gt;&#xA;&lt;p&gt;Alcuni anni fa si parlava in senso negativo di &lt;a href=&#34;https://en.wikipedia.org/wiki/Software_bloat&#34;&gt;&lt;em&gt;bloatware&lt;/em&gt;&lt;/a&gt;, di quei programmi inutilmente grossi e tanto poco ottimizzati da richiedere grosse risorse hardware anche per svolgere funzioni relativamente semplici.&lt;/p&gt;&#xA;&lt;p&gt;A volte i programmatori dimenticano due concetti fondamentali della buona programmazione, cercare la semplicità e usare lo strumento più adatto per il compito specifico, e si perdono in inutili (e stucchevoli) esercitazioni di stile. Succede a chi propone banalmente di usare file CSS enormi al posto di semplici immagini grafiche, ma succede anche in tanti altri casi ben peggiori.&lt;/p&gt;&#xA;&lt;p&gt;A parte questo, il post è stato anche un&amp;rsquo;occasione per parlare di &lt;code&gt;awk&lt;/code&gt;, uno strumento poco conosciuto ma molto otente, in particolare quando si tratta di analizzare e trasformare dati contenuti in file di testo.&lt;/p&gt;&#xA;&lt;p&gt;Uno strumento che è diventato parte integrante da anni della mia routine di lavoro quotidiana. Sarebbe bello poterne riparlare.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>La settimana di Python</title>
      <link>https://static.233.196.69.159.clients.your-server.de/it/2015/10/13/la-settimana-di-python/</link>
      <pubDate>Tue, 13 Oct 2015 18:00:00 +0000</pubDate>
      <guid>https://static.233.196.69.159.clients.your-server.de/it/2015/10/13/la-settimana-di-python/</guid>
      <description>&lt;p&gt;La solita &lt;a href=&#34;https://www.packtpub.com/&#34;&gt;Packt&lt;/a&gt; sta celebrando da ieri la &lt;a href=&#34;https://www.packtpub.com/packt/offers/pythonweek&#34;&gt;settimana di Python&lt;/a&gt;, nel corso della quale offrirà uno sconto del 20% sui suoi libri su Python e un &lt;a href=&#34;https://www.packtpub.com/packt/offers/free-learning&#34;&gt;volume gratuito al giorno&lt;/a&gt; sull&amp;rsquo;argomento.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt; è a mio modesto parere il linguaggio di programmazone più interessante che ci sia in giro, facile da imparare ma anche veloce, potente ed estensibile.&#xA;Un aspetto non trascurabile è che può essere utilizzato sia in modo procedurale, come il Fortran o il C, che nella più moderna modalità ad oggetti (e perfino in modo misto), rendendo più semplice padroneggiare i concetti, piuttisto astrusi a dire il vero, della programmazione orientata agli oggetti.&lt;/p&gt;&#xA;&lt;p&gt;Non voglio fare sempre pubblicità a Packt, ma trovo molto lungimirante la sua politica di offrire gratis tanti volumi stimolanti e che coprono uno spettro di interessi molto vasto. Prendi quelli gratis ma prima o poi qualcuno lo compri pure.&lt;/p&gt;&#xA;&lt;p&gt;Mi sembra una occasione da non farsi sfuggire.&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
