Autore: PugliaSOS

  • Alert

    ISTRUZIONI

  • 03 Incontro del 18-1-2025

    Range

    La sequenza di numeri interi consecutivi è di uso così frequente in Python che è stata definita una funzione specifica, range(), per crearla.
    La sintassi:

    range (n1, n2, p)

    dove

    • n1 l’intero da cui iniziare la sequenza; è opzionale e per default è 0
    • n2 l’intero, escluso, con cui concludere la sequenza
    • p l’incremento (passo) della sequenza; è opzionale e per default è 1
    Indipendentemente dall'intervallo che rappresenta, la funzione range() memorizza solo i valori di inizio, fine ed incremento, per cui consuma molto meno memoria di quella che occuperebbe una lista.

    Esempio

    a= range(3,6)
    for x in a:
        print(x, end=’\t’)

    Risultato
    3 4 5

    Esempio

    a= range(6)
    for x in a:
    print(x, end='\t')

    Risultato
    0 1 2 3 4 5

    Esempio

    a= range(3,9,2)
    for x in a:
        print(x, end='\t')

    Risultato
    3 5 7

     

    � Esercizio
    Scrivere un programma che determini i divisori di un numero naturale digitato dall’utente.

    Una possibile soluzione

    n = int(input("Digita il numero naturale del quale determinare i divisori: "))
    print(f"I divisori di {n} sono:")
    for i in range(1, n+1):                            #range(1,n+1) crea una sequenza di numeri da 1a n+1 escluso
        if n % i == 0:
            print(i, end='    ')

    � Esercizio
    Visualizzare la tabellina di un numero naturale da 1 a 10 digitato dall’utente

    Una possibile soluzione

    n = int(input("Digita un numero intero da 1 a 10 del quale visualizzare la tabellina: "))
    for i in range(1,11):
        print(n * i, end="
    ")

    � Esercizio
    Verificare se il numero naturale digitato dall’utente è un numero primo.

    Una possibile soluzione

    n = int(input("Digita il numero naturale del quale verificare  se è un numero primo: "))
    primo = True
    for i in range(2,
    n, 1):
        if n%i == 0:
            primo = False
    if primo:
        print(f"Il numero {n} è primo!")
    else:
        print(f"Il numero {n} non è primo!")

     

    Il 2 non viene preso in considerazione dal ciclo, per cui non altera il contenuto della variabile primo che permane col valore True.
    Tale soluzione è volutamente elementare, vedremo nella fase dedicata a
    lla Matematica come ottimizzarla.

    Tuple

    La tuple è un insieme ordinato di più elementi in un’unica variabile, e fin qui la definizione coincide con quella della lista, ma allora per cosa sono simili e per cosa differiscono?

    Le differenze

    • Innanzitutto denotiamo la differenza nella loro creazione:
           a=[a,b,c,d,e] è una lista
           b=(a,b,c,d,e) è una tupla
      Una tupla è definita con gli elementi posti fra una parentesi tonda di apertura ed una di chiusura o semplicemente, senza parentesi, scrivendo i suoi elementi separati da virgole (sconsigliato).1
    • La differenza fondamentale tra le tuple e le liste è che mentre le prime non possono essere modificate, le seconde sì: cioè le tuple sono oggetti immutabili.
    • Fra una tupla ed una lista contenenti gli stessi elementi, la tupla è più efficiente in termini di memoria.
      Poiché le liste sono mutabili, Python deve riservare memoria aggiuntiva per consentire, dopo la sua creazione, una eventuale estensione della sua dimensione con l’aggiunta o modifica dei suoi elementi. Differentemente accade per le tuple che hanno dimensione fissa, poiché immutabili, e per le quali Python riserva il minimo della memoria richiesta dai dati.
    • Per lo stesso motivo anzidetto, le tuple hanno una migliore efficienza temporale, soprattutto nella fase di ricerca

    Le similitudini

    • Sia nelle tuple che nelle liste è possibile archiviare qualsiasi tipo di dati.
    • Sia le tuple che le liste sono ordinate.
    • È possibile scorrere gli elementi contenuti sia nelle tuple che nelle liste, poiché sono entrambi tipi di dati sequenziali.
    • Si possono effettuare sulle tuple tutte quelle operazioni previste con le liste che non ne prevedano modifiche; in particolare si può accedere sia agli elementi delle tuple che delle liste usando le parentesi quadre e un indice ([indice]).

    Per motivi di efficienza, se si hanno dati che non dovrebbero cambiare, è opportuna la scelta del tipo di dati tupla piuttosto che lista.

    Oggetti e valori

    Se vengono create due diverse variabili alle quali viene assegnato lo stesso valore di tipo lista

         var1=['a','b','c','d','e']
         var2=['a','b','c','d','e']

    e si ricavano i loro identificatori

         print(id(var1))
         print(id(var2))

    140307786079040
    140307782128512

    si scopre che le liste hanno un comportamento diverso dai dati numerici e le stringhe, due liste diverse fanno SEMPRE riferimento ad oggetti diversi.

    Occorre però fare una precisazione; si analizzi il seguente programma:

    var1=['a','b','c','d','e']
    var2=var1

    e si ricavano i loro identificatori

    print(id(var1))
    print(id(var2))

    140091535792960
    140091535792960

    var1 e var2 si riferiscono allo stesso oggetto (si può dire che sono due alias dello stesso oggetto). Se modifico var1 viene modificato il valore di var2, poiché fanno riferimento allo stesso oggetto; dunque conviene evitare la creazione di un alias ed effettuare una copia che assume un id diverso.

    Le matrici (*)

    La matrice è una lista annidata i cui elementi sono le liste costituite dagli elementi di una riga. Chiariamo con un esempio. La matrice può essere rappresentata dalla lista annidata di tre elementi

    M = [ [1, 2, 3, 4], [5, 6, 7, 8],[9, 10, 11, 12]]

    per cui M[0] seleziona la prima riga, M[1] la seconda, M[2] la terza. Per individuare un singolo elemento della matrice si deve usare un doppio indice: il primo per la riga ed il secondo per la colonna; ad esempio

    M [2] [2]

    individua l’elemento all’incrocio fra la terza riga e la terza colonna, cioè 11.

    Va sottolineato che questo è uno dei vari modi di rappresentare le matrici; un’alternativa, ad esempio, è quella di rappresentare la matrice come una lista di colonne invece che di righe.

    Attività ludica e di consolidamento con la turtle graphics 2

    Le procedure grafiche ben si prestano al consolidamento dei costrutti fin qui appresi, poichè ne consentono un riscontro visivo immediato ed inoltre aprono la strada alla progettazione delle funzioni.
    Un aiuto viene dal modulo grafico turtle che consente la creazione di immagini grazie alla turtle graphics3, modulo già integrato in quasi tutte le installazioni di Python.
    Il modulo turtle crea una tartaruga, rappresentata simbolicamente nel nostro caso dalla punta di una freccia; durante il movimento, ottenuto con comandi esplicativi e molto semplici, trasporta una penna con la quale può lasciare traccia del suo movimento. Al momento della sua creazione la tartaruga è orientata a destra ed è posta al centro dello schermo che viene individuato come un sistema di assi cartesiani ortogonali il cui punto di origine è proprio il suo centro.

    La tartaruga nasce con coordinate (0,0) ed orientata a destra.

    Per iniziare a disegnare è ovviamente necessario importare il modulo:

    import turtle

    che mette a disposizione moltissimi metodi4, i più popolari dei quali vengono riportati nelle seguenti tabelle, raggruppati per omogeneità.

    Movimento

    Descrizione

    forward(pixel)

    fd(pixel)

    Sposta la tartaruga in avanti, nell’orientamento contestuale, di una distanza pari al numero di pixel specificato come parametro.

    backward(pixel)

    bk(pixel)

    Sposta la tartaruga indietro, nel verso contestuale, di una distanza pari al numero di pixel fornito come parametro.

    left(angolo)

    lt(angolo)

    Ruota in senso antiorario dell’angolo sessagesimale specificato.

    right(angolo)

    rt(angolo)

    Ruota in senso orario dell’angolo sessagesimale indicato.

    goto(x,y)

    Sposta la tartaruga nel punto di coordinate (x,y); home (la tana) ha coordinate (0,0).

    home()

    Sposta la tartaruga nel punto di coordinate (0,0) cioè al centro dello schermo e la orienta a destra.

    reset()

    Dopo aver pulito lo schermo, colloca la tartaruga nel punto di coordinate (0,0) cioè al centro dello schermo e la orienta a destra.

    Se si vuol pulire lo schermo, lasciando inalterata la posizione della tartaruga è messo a disposizione il metodo clear().

    speed(velocità)

    Imposta la velocità della tartaruga con un argomento intero compreso tra 0 e 10: da 1 a 10 con un’animazione sempre più rapida sia nel disegno delle linee che nella rotazione della tartaruga, mentre con la  velocità impostata su 0 tutto avviene con una velocità ancora più alta delle precedenti.

     

    I primi quattro metodi impartiscono spostamenti relativi, i restanti imprimono spostamenti assoluti.

    Va notato che un parametro negativo per forward produce un movimento indietro e non in avanti, cioè opposto alla traduzione letterale del metodo; in maniera analoga si comportano backward, left e right.

    Esempio

    Disegniamo un quadrato di lato 200 pixel.

    Quadrato.png

    1. importare il modulo turtle: import turtle
    2. mettere giù la penna in modo da lasciare traccia del movimento: turtle.pd()
    3. muovere la penna in avanti di 200 px: turtle.fd(200)
    4. ruotare la tartaruga di 90° verso destra (angolo esterno!): turtle.rt(90)
    5. ripetere l’azione del punto 3
    6. ripetere l’azione del punto 4
    7. ripetere l’azione del punto 3
    8. ripetere l’azione del punto 4
    9. ripetere l’azione del punto 3
    10. ripetere l’azione del punto 4 (per portare la tartaruga all’orientamento iniziale)

    In definitiva il programma diventa:

    import turtle

    turtle.fd(200)
    turtle.rt(90)
    turtle.fd(200)
    turtle.rt(90)
    turtle.fd(200)
    turtle.rt(90)
    turtle.fd(200)
    turtle.rt(90)
    turtle.mainloop()

    L’angolo di rotazione della tartaruga è pari all’angolo esterno del lato; poiché, qualunque sia il numero dei suoi lati, la somma degli angoli esterni di un poligono è di 360°, l’angolo di cui la tartaruga deve ruotare è pari a (360/4)°

    Mandando in esecuzione il programma si apre la finestra:

     Finestra.png

    Con il metodo mainloop() il programma attenderà che la finestra grafica della tartaruga venga chiusa.

    Controllo della penna

    Descrizione

    penup()

    pu()

    up()

    Solleva la penna; la tartaruga non lascia traccia durante il movimento.

    pendown() pd() down()

    Abbassa la penna; la tartaruga lascia traccia durante il movimento.

    pensize(larghezza)

    width(larghezza)

    Imposta la larghezza della punta della penna.

    pencolor(nomeColore)

    Imposta il colore della penna indicato come stringa: “red”, “green”, “yellow”, “blue”, “orange”, “gray”, “purple”, “black”, …

    pencolor(r, g, b)

    Imposta il colore della penna sul colore RGB specificando i valori del rosso, verde e blu, con valori fra 0 e 255.

     

    Esempio

    Disegniamo il triangolo avente i vertici nei punti di coordinate A(-50,-70), B(150,20) e C(200,200)Triangolo.png

    import turtle 
    turtle.width(4)
    turtle.pencolor("blue")
    turtle.penup()
    turtle.goto(-50,-70)
    turtle.pendown()
    turtle.goto(150,20)
    turtle.goto(200,200)
    turtle.goto(-50,-70)
    turtle.mainloop()

     

    Stato della tartaruga

    Descrizione

    hideturtle() ht()

    Nasconde la tartaruga. Può essere utile per i disegni complessi, poiché velocizza notevolmente il disegno.

    showturtle() st()

    Rende visibile la tartaruga.

    isdown()

    Ritorna 
    True se la penna è abbassata, 
    False se la penna è alzata.

     

     

    Altri metodi di nostro interesse

    Descrizione

    bgcolor(“colore“)

    Personalizza il colore di sfondo della finestra grafica

    delay(millisecondi)

    Ritarda l’aggiornamento del disegno di un tempo pari ai millisecondi specificati.

    numinput(titolo,prompt,default,valMin,valMax)

    Apre una finestra di dialogo per l’immissione di un numero.

    titolo è il titolo della finestra di dialogo

    prompt è un testo che suggerisce quali informazioni numeriche immettere

    default è il valore predefinito; opzionale

    valMin è il minimo del valore da immettere; opzionale

    valMax è il massimo del valore da immettere; opzionale

    Se vengono specificati valMin e valMax, il numero da digitare deve essere compreso nell’intervallo da essi individuato, altrimenti viene emesso un messaggio di errore e la finestra di dialogo rimane in attesa di una correzione del dato.

    Il valore immesso come stringa viene restituito dopo averlo trasformato in float.

    circle(raggio)

    Disegna un cerchio del raggio assegnato, partendo della posizione della tartaruga; in senso orario se il raggio è negativo, antiorario se positivo.

     

    Dare un nome alla tartaruga

    Se importiamo il modulo con:

    import turtle as tarta

    non dovremo più impartire i comandi con riferimento all’oggetto turtle, bensì a tarta; ad esempio per spostare la tartaruga in avanti, scriveremo:

    tarta.fd(100)

    È possibile pervenire allo stesso risultato creando tarta come una istanza della libreria turtle:

    import turtle
    tarta=turtle.Turtle()

    Va notato che turtle è l’istanza di default.

    Quella della creazione delle istanze è una cosa utile laddove si vogliano tracciare più disegni contemporaneamente affidandosi a più oggetti.

    Per semplicità nella creazione degli script, nel proseguo importeremo la libreria ponendo in cima al programma la riga

    from turtle import *

    che ci permetterà di non usare la notazione punto e di scrivere semplicemente il metodo, dando per scontato che essa è riferita all’istanza turtle. ad esempio scriveremo:

    fd(200)

    invece di turtle.fd(200).

    � Esercizio

    Come è facile notare, nel tracciare il quadrato viene ripetuta per quattro volte una coppia di comandi: uno di spostamento ed uno di rotazione.
    Ottimizzare, con un ciclo for, il codice per disegnare il quadrato di lato 200 px seguendo il seguente programma scritto in linguaggio naturale:

    se la penna è su
    porta la penna giù
    ripeti per 4 volte
    avanti 200
    ruota a destra di 90°

    Una possibile soluzione:

    from turtle import *

    if (isdown() == False):
         pendown
    for i in range(4):
         fd(200)
         rt(90)

    mainloop()

    Una seconda soluzione:

    from turtle import * 
    n=1
    while n<=4:
    fd(200)
         right(90)
         n=n+1
    mainloop()

    � Esercizio

    Creare uno script che disegni un triangolo equilatero di lato 200 px, tenendo presente che ora i lati sono 3 per cui l’angolo esterno è di (360/3)°. Può essere di aiuto il seguente algoritmo in linguaggio naturale:

     

    Triangolo_equilatero.png

    se la penna è su
    porta la penna giù
    ripeti per 3 volte
    avanti 200
    ruota a sinistra di (360/3)

     

     

    Una possibile soluzione:

    from turtle import *
    if (isdown() == False):
        pendown()
        for i in range(3):
        fd(200)
        lt(360/3)
    mainloop()

    Incapsulamento5

    Perché non insegnare alla tartaruga come costruire un quadrato o un triangolo, senza dovergli ripetere i comandi più volte?

    Lo possiamo fare definendo una funzione, cioè un insieme di comandi a cui diamo un nome. Ad esempio, se diamo un nome quadrato allo script:

    for i in range(4):
         fd(200)
         lt(360/4)

    basterà dire quadrato() alla tartaruga, perché essa tracci un quadrato di lato pari a 200 px. Ad esempio:

    from turtle import * 
    def quadrato():
         for i in range(4):
              fd(200)
              lt(360/4)
    if (isdown == False):
          pendown()
    quadrato()
    mainloop()

    def sta ad indicare che si sta definendo una funzione; def richiede che accanto, dopo uno spazio, venga indicato il nome che si vuole assegnare alla funzione seguito da una parente tonda aperta, una chiusa e due punti. Subito dopo vanno inseriti i comandi indentati rispetto a def; una riga non indentata pone fine all’incapsulamento.

    � Esercizio

    20_quadratini.png

    Disegnare 20 quadrati di lato 10 px distanziati fra loro.

    Una possibile soluzione:

    from turtle import * 
    def quadrato():
         for i in range(4):
              fd(10)
              lt(360/4)
    speed(0)
    penup()
    goto(-200,0)
    hideturtle()
    for i in range(20):
         pendown()
         quadrato()
         penup()
         forward(20)
    mainloop()

    _______________________________________________________________

    NOTE

    1 È possibile creare una tupla costituita da un singolo elemento, purché aggiungiamo una virgola.

    2  https://docs.python.org/3/library/turtle.html#starting-a-turtle-environment

    3 È un’implementazione del Logo, sviluppato nel 1967 ad opera di Wally Feurzeig, Seymour Papert e Cynthia Solomon.

    4 Azioni che può fare.

    5 Consiste nell’inglobare una serie di istruzioni in una funzione.

     

     

  • 03 Incontro del 11-1-2025

    Useremo 3 metodi per creare o rappresentare una Matrice LED :

    1. mediante un array bidimensionale di byte

    2. con 3 vettori di numeri binari

    3. con 3 vettori di numeri esadecimali

     

    1. Creare un bitmap LED per LED

     

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    0 

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    2

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    3

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    4

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    5

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    6

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    7

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

     

    Un cuore nel bitmap

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    0 

    0

    0

    1

    1

    0

    0

    0

    1

    1

    0

    0

    0

    1  

    0

    1

    1

    1

    1

    0

    1

    1

    1

    1

    0

    0

    2

    0

    1

    1

    1

    1

    1

    1

    1

    1

    1

    0

    0

    3

    0

    0

    1

    1

    1

    1

    1

    1

    1

    0

    0

    0

    4

    0

    0

    0

    1

    1

    1

    1

    1

    0

    0

    0

    0

    5

    0

    0

    0

    0

    1

    1

    1

    0

    0

    0

    0

    0

    6

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    0

    7

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

     

    Il codice 1

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED; //creiamo una istanza
    byte cuoreBit[8][12] = { // 96 byte
    { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
    { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    };
    void setup() {
      matriceLED.begin();
      matriceLED.renderBitmap(cuoreBit, 8, 12);
    }
    void loop() {
    }
    È necessario applicare all'oggetto matriceLED il metodo renderBitmap(cuoreBit, 8, 12) per vedere l'immagine statica (fotogramma) del cuore su di esso. Il metodo renderBitmap accetta un array di elementi booleani in cui ciascun elemento corrisponde ad un singolo pixel.2

    Lampeggio nei vertici della matrice

    L’indirizzo di un elemento della matrice è costituito dal nome della matrice seguito dalla riga e colonna di appartenenza ciascuna racchiusa in una parentesi quadra; ad esempio

      nomeMatrice [2][4]

    è l’indizzo del LED che si trova all’incrocio della terza riga con la quinta colonna.

    Per cui la scrittura nel codice di:

      nomeMatrice [2][4] = 0

    determina lo spegnimento del LED in questione, mentre:

       nomeMatrice [2][4] = 1

    la sua accenzione.

    Ciò premesso,

    • Scrivere il codice che faccia lampeggiare i vertici del rettangolo matriceLED.

    Una possibile soluzione:

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED;
    uint8_t frame[8][12];
    void setup() {
      matriceLED.begin();
    }
    void loop() {
      frame[0][0] = 1;
      frame[0][11] = 1;
      frame[7][0] = 1;
      frame[7][11] = 1;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
      frame[0][0]=0;
      frame[0][11]=0;
      frame[7][0]=0;
      frame[7][11]=0;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
    }
    • Se nel loop dovessimo inserire una renderizzazione con una pausa dopo ogni singola variazione della matrice, cosa otterremmo? Perchè?

    Un partecipante all’incontro ha voluto incrociare i due precedenti programmi:

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED; 
    byte frame[8][12] = { // 96 byte
    { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
    { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    };
    void setup() {
      matriceLED.begin();
      matriceLED.renderBitmap(frame, 8, 12);
    }
      void loop() {
      frame[0][0] = 1;
      frame[0][11] = 1;
      frame[7][0] = 1;
      frame[7][11] = 1;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
      frame[0][0]=0;
      frame[0][11]=0;
      frame[7][0]=0;
      frame[7][11]=0;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
    }

    ________________________________________________________

    Note

    1https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix/

    2 ll rendering (letteralmente restituzione grafica), italianizzato come renderizzazione, identifica la generazione di una immagine

  • 02 Incontro del 14-12-24

    Gli appunti dell’incontro del gruppo di approfondimento del linguaggio Python.

    Operazioni sulle liste

    invitati = [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]

    daInvitare = [‘Giuseppe’]

    Concatenare

    +

    c = invitati + daInvitare
    print(c)
    [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’, ‘Giuseppe’]

    Lista ripetuta

    *

    c = daInvitare * 4
    print(c)
    [‘Giuseppe’, ‘Giuseppe’, ‘Giuseppe’, ‘Giuseppe’]

    Porzione1

    [n1: n2]

    c = invitati[1:3]
    print(c)
    [‘Michelangelo’, ‘Riccardo’]

     

    I metodi

    Approfondiamo tutti metodi applicandoli uno di seguito all’altro alla lista:

    invitati = [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]

    • append(): aggiunge alla fine della lista l’elemento che riceve come argomento.

    Esempio:

    invitati = [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]
    invitati.append(‘Giovanni’)
    print(invitati)

    Risultato:

    [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’, ‘Giovanni’]

    che ora è la nuova lista invitati.

    • count(valore): ritorna il numero di ricorrenza di un determinato valore.

    Continuiamo eseguendo

    x=invitati.count(‘Giovanni’)
    print(x)

    Risultato

    2

    poiché prima abbiamo aggiunto Giovanni in fondo alla lista.

    • insert(posizione, oggetto): inserisce un elemento nuovo alla lista nella posizione specificata. Necessita di due argomenti: un intero che rappresenta la posizione e l’altro che è l’elemento da inserire.

    Alla luce dei metodi applicati, ora la lista è

    invitati = [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’, ‘Giovanni’]

    digitiamo

    invitati.insert(1, ‘Paola’)
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Paola’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’, ‘Giovanni’] è stata aggiunta Paola in seconda posizione.

    • reverse(): inverte l’ordine degli elementi nella lista.

    invitati.reverse()
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Angelo’, ‘Riccardo’, ‘Michelangelo’, ‘Paola’, ‘Giovanni’]

    • sort(): ordina la lista

    invitati.sort() # ordina la lista in senso alfabetico crescente
    print(invitati)

    Risultato

    [‘Angelo’, ‘Giovanni’, ‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’] Come si può notare, il metodo sort() altera il contenuto della lista; se se ne vuol mantenere l’ordine originale degli elementi, può risultare utile l’uso della funzione sorted2

    invitati = [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]
    invitati_ord = sorted(invitati)
    print(invitati)
    print(invitati_ord)

    Risultato

    [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]

    [‘Angelo’, ‘Giovanni’, ‘Michelangelo’, ‘Riccardo’]

    • pop(indice): rimuove e restituisce l’elemento nella posizione indicata o l’ultimo della lista qualora la posizione fosse omessa.

    invitati.pop(1)
    print(invitati)

    Risultato

    [‘Angelo’, ‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’]

    Se invece del semplice invitati.pop(1) avessimo digitato x = invitati.pop(1),

    Giovanni non solo sarebbe stato rimosso dalla lista, ma sarebbe stato assegnato alla variabile x.

    • remove(oggetto): rimuove dalla lista la prima istanza dell’elemento passato come argomento.

    invitati.remove(‘Angelo’)
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’]

    • index(valore): restituisce l’indice della prima occorrenza dell’elemento specificato.

    print(invitati.index(‘Michelangelo’))

    Risultato

    1

    cioè in seconda posizione.

     extend(lista): aggiunge gli elementi di una lista alla lista corrente.

    invitati.extend([‘Angelo’, ‘Federico’, ‘Aurora’])
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’, ‘Angelo’, ‘Federico’, ‘Aurora’]

    • copy(): restituisce una copia della lista.

    copia_invitati = invitati.copy()
    print(copia_invitati)

    Alternativa

    copia = invitati[:]
    print(copia)
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’, ‘Angelo’, ‘Federico’, ‘Aurora’] [‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’, ‘Angelo’, ‘Federico’, ‘Aurora’]

    • clear(): svuota la lista.

    invitati.clear()
    print(copia)
    print(invitati)

    Due alternative:

    • con l’operatore del

    del invitati[:]
    print(copia)
    print(invitati)

    • assegnando una lista vuota

    invitati[:] = [ ]
    print(copia)
    print(invitati)

    Risultato

    [‘Giovanni’, ‘Michelangelo’, ‘Paola’, ‘Riccardo’, ‘Angelo’, ‘Federico’, ‘Aurora’]
    [ ]

    La lunghezza di una lista

    Anche per determinare la lunghezza di una lista è possibile utilizzare la funzione len() cui abbiamo fatto ricorso per determinare la lunghezza di una stringa; con una differenza però: una lista annidata viene contata come un solo elemento, indipendentemente dal numero degli elementi di cui è costituita.

    Nei cicli è preferibile usare come parametro la funzione len(), piuttosto che un valore costante, come limite superiore; ciò consente una generalizzazione poiché si evita di apportare modifiche se dovesse cambiare la lunghezza della lista. Occorre ribadire ancora una volta che l’ultimo elemento della lista di lunghezza x, occupa la posizione x-1, e non x, sempre perché il conteggio parte da 0 e non da 1.

    List comprehensions

    È una sintassi che permette di per creare una lista basandosi su altre liste, comprimendo un’iterazione e una trasformazione su di esse in una sola riga di codice.
    Una list comprehension (comprensione di lista in Italiano3) è creata utilizzando parentesi quadre con all’interno una espressione ed un ciclo for , opzionalmente con if se necessari.

    Esempio

    Scrivere un programma che, partendo dalla lista

    lista1 = [‘Barletta’, ‘Andria’, ‘Trani’, ‘Corato’, ‘Canosa’]

    ne costruisca una seconda contenente, nell’ordine, la lunghezza degli elementi della prima.

    Una prima soluzione

    lista1 = [‘Barletta’, ‘Andria’, ‘Trani’, ‘Corato’, ‘Canosa’]
    lista2 = [ ]
    for stringa in lista1:4
    lista2.append(len(stringa))
    print(lista2)

    [8, 6, 5, 6, 6]

    Una seconda soluzione con una list comprehension:

    lista1 = [‘Barletta’, ‘Andria’, ‘Trani’, ‘Corato’, ‘Canosa’]
    print([len(parola) for parola in lista1])

    [8, 6, 5, 6, 6]

    �Esercizio

    Creare una lista contenente i quadrati degli elementi della lista [1,2,3,4,5,6,7,8,9,10]

    Una possibili soluzione:

    basi=[1,2,3,4,5,6,7,8,9,10]
    quadrati=[n**2 for n in basi]
    print(quadrati)

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    Esempio con l’if

    Creare una lista contenente i quadrati dei numeri pari della lista [1,2,3,4,5,6,7,8,9,10]

    basi=[1,2,3,4,5,6,7,8,9,10]
    quadrati=[n**2 for n in basi if n % 2 == 0]
    print(quadrati)

    [4, 8, 12, 16, 20]

     

    ______________________

    NOTE

    1 Si comporta con gl’indici come visto nelle stringhe

    2 Per approdimenti della funzione sorted:
    https://www.tuttofaredigitale.it/python-funzioni-integrate/python-sorted
    https://www.andreaminini.com/python/funzione-sorted-python

    3 Per alcuni, più che di comprensione di lista, si dovrebbe parlare di compressione!

    4 Esegui i comandi che seguono per ogni elemento della lista, la prima volta per quello di indice 0, la seconda con quello di indice 1 e così via fino all’ultimo elemento della lista.

  • 02 Incontro del 7-12-24

    �Esercizio

    Creare nel LED EDITOR MATRIX una animazione con i seguenti fotogrammi:

    pilaInCarica.png

    con un tempo di transizione di 600 ms.
    Per creare un ciclo continuo a video nell’editor: Maiusc. + Barra spaziatrice

    Pillola informatica: le variabili di tipo intere

    int8_t

    un valore con segno a 8 bit
    da -128 a +127
    char

    1 byte di RAM

    uint8_t

    un valore senza segno a 8 bit
    da 0 a 255
    byte

    1 byte di RAM

    int16_t

    un valore con segno a 16 bit
    da -32.768 a +32.767
    int

    2 byte di RAM

    uint16_t è di

    valore senza segno a16 bit
    da 0 a 65.535
    unsigned int

    2 byte di RAM

    int32_t

    valore con segno a 32 bit
    da -2.147.483.648 a +2.147.483.647
    long

    4 byte di RAM

    uint32_t

    valore senza segno a 32 bit
    da 0 a 4.294.967.295
    unsigned long

    4 byte di RAM

     

    Per comprendere i danni provocati da un overflow basti pensare al display di un contagiri costituito da soli due digit; allorchè si passa da 99 a 100, compaiono solo i due zeri poichè l’uno va fuori campo.

    Libreria Serial

    Con Arduino è possibile attivare una comunicazione seriale per inviare e ricevere dati tramite un cavo USB (Universal Serial Bus) con la libreria Serial già integrata nell’IDE. Tale libreria crea un oggetto denominato, di default, Serial.

    All’interno di questa libreria vi sono funzioni (dette anche metodi) come:

    Serial.begin(velocità);
    da usare nel setup,
    predispone Arduino a ricevere ed inviare informazioni tramite la porta seriale.

    velocità: in bit al secondo (baud1): normalmente 9600 bit/s.

    Serial.print(valore);
    invia al monitor seriale il contenuto della variabile valore o una stringa posta tra doppie virgolette o un carattere posto fra virgolette semlici2, senza mandare a capo il cursore.

    Serial.println(valore);
    come prima, ma il cursore va a capo.

    Serial.available();
    restituisce il numero intero dei caratteri che attendono di essere letti sulla porta seriale; restituisce 0 se il buffer è vuoto.

    Serial.read();
    restituisce, sotto forma di carattere, il primo byte in input dal buffer di ricezione seriale 3.

    Serial.readString();
    legge tutta la stringa presente nel buffer di ricezione seriale.

    Serial.print(“\t”);
    introduce una tabulazione.

    Serial.parseInt();4
    legge i caratteri che rappresentano cifre e li restituisce nella rappresentazione numerica.

    Serial.parseFloat();
    legge i caratteri che rappresentano numeri decimali e li restituisce nella rappresentazione numerica.

    La comunicazione seriale

    È un processo di invio di bit uno alla volta; quando i dati arrivano ad Arduino, vanno nel buffer di ricezione seriale. Arduino è dotato di un componente hardware chiamato ricevitore/trasmettitore asincrono universale (UART): tale componente quando arrivano i bit di dati dal computer, li assembla a otto ad otto e li memorizza nel buffer di ricezione seriale.

    Quando si inviano dati, può accadere che al termine della trasmissione venga aggiunto un carattere di terminazione: un CR (Carriage Return, ritorno carrello) o un LF (Line Feed, fine riga) o entrambi; ciascuno di essi aggiungerebbe un byte al buffer di ricezione seriale e questo potrebbe generare qualche effetto indesiderato. Per evitare che ciò possa accadere, è opportuno selezionare Entrambi CR & NL nel menu a discesa che compare nella finestra del Monitor Seriale

    ll monitor seriale è anche utile per verificare se il codice Arduino sta dando i risultati desiderati e risolvere eventuali problemi (tecnica conosciuta come debug seriale).

    Inoltre va puntualizzato che tutto ciò che viene immesso o visualizzato nel Monitor seriale è una stringa5 o un carattere!

    Approfondimenti
    Per comprendere la comunicazione seriale:
    https://dumblebots.com/2019/05/06/arduino-tutorial-its-getting-serial-part-a/
    https://www.programmingelectronics.com/serial-read/

    Variabile globale e variabile locale

    Approfondiamo, attraverso il Serial Monitor, la differenza tra variabile globale e variabile locale.

    • Globale
      È una variabile dichiarata al di fuori delle funzione, compreso setup() e loop(), visibile e modificabile in ogni parte del programma.
    • Locale
      Esse sono visibili solo all’interno delle funzioni e cicli dove vengono definite; viene così ridotta la possibilità di commettere errori di scrittura nelle variabili.
      Due variabili locali, definite in differenti parti del programma, possono avere lo stesso nome e contenere valori differenti, poiché una variabile locale ha vita e visibilità solo nella funzione o ciclo dove viene dichiarata.
      Una variabile che viene definita all’interno di parentesi graffe è una variabile locale.
    • Statica
      È una variabile locale che si comporta come una globale. Infatti è visibile solo dalla funzione in cui viene creata, solo che non viene distrutta quando si esce dalla funzione e ricreata ogni volta che viene chiamata la funzione: sarà definita ed inizializzata solo la prima volta e persisterà e conserverà il proprio valore all’interno della funzione. Al momento non è di nostro interesse!
      La parola chiave è static

    Esempio di variabile globale

    int contatore=1;
    int attesa=1000;

    void setup() {
       Serial.begin(9600);
    }

    void loop() {
       Serial.print(“Ora la variabile contatore contiene il numero: “);
       Serial.println(contatore);
       /*Serial.println(“Ora la variabile contatore contiene il numero: ” + String(contatore)); */
       contatore=contatore+1;
       delay(attesa);
    }

    Esempio di variabile locale

    Lo stesso programma di prima, solo che contatore viene definito in setup, invece che prima. Poiché la variabile è locale, si ottiene un errore:

    Compilation error: ‘contatore’ was not declared in this scope

    Pillola Informatica: gli array

    Supponiamo di voler memorizzare una cinquina di estrazione al lotto, due metodi:

    Con 5 variabili (cinque scatole)
    uint8_t numeroEstratto1=9;
    uint8_t numeroEstratto2= 21;
    uint8_t numeroEstratto3= 45;
    uint8_t numeroEstratto4= 90;
    uint8_t numeroEstratto5= 46;

    Con un array di dimensione 5 (una scatola con 5 scomparti)

    uint8_t numeriEstratti [5];
    numeriEstratti [0]=9;
    numeriEstratti [1]=21;
    numeriEstratti [2]=45;
    numeriEstratti [3]=90;
    numeriEstratti [4]=46;

    oppure, più sbrigativamente

    uint8_t numeriEstratti [5]={9,21,45,90,46}

    9

    21

    45

    90

    46

     

    Array unidimensionale o vettore

    Un vettore è un insieme omogeneo di dati, i cui valori vengono contrassegnati, e quindi vi si accede ad ognuno di essi, con un indice.
    Il primo elemento di un vettore costituito da N elementi (di dimensione N) è contrassegnato con lo 0, l’ultimo con N-1.

    Valore

    a

    b

    c

    d

    e

    f

    Indice

    0

    1

    2

    3

    4

    5

     

    Sintassi

    int unArray[6]; // dichiarazione di un array di dimensione 6, senza inizializzarlo

    byte unArray[6] = {‘a’,’b’,’c’,’d’,’e’,’f’}; // dichiarazione di un array di dimensione 6 inizializzato

    Se si dichiara una dimensione maggiore del numero di elementi utilizzati nella inizializzazione, vengono aggiunti spazi vuoti alla fine dell’array: in un secondo momento si potranno aggiungere gli altri elementi.

    byte unArray[]={‘a’,’b’,’c’,’d’,’e’,’f’}; // dichiarazione di un array inizializzato di  dimensione pari al numero degli elementi inseriti;

    Per recuperare il valore di un elemento dell’array è necessario avere una variabile di lettura o di accesso alla quale assegnare il valore richiesto.

    Un valore nell’array può essere richiamato con il nome dell’array e l’indice numerico della posizione occupata nell’array, posto fra parentesi quadre.

    int variabile = unArray[3] // nell’esempio precedente equivale a variabile = d

    Semplice è anche assegnare un valore ad un elemento di un array, ad esempio

    unArray[3] = ‘d’;

    assegna il valore d al quarto elemento.

    ATTENZIONE: se si accede agli elementi di un array di dimensione N con un indice superiore a N-1, si va in una zona di memoria diversa da quella occupata dall’array e si commettono errori in fase di lettura e danni in quella di scrittura!

    Array bidimensionale o matrice

    Essi sono delle strutture dati bidimensionali, in pratica delle tabelle, in cui organizzare elementi omogenei, ciascuno individuato da due indici, il primo indice è detto indice di riga, il secondo indice di colonna.

    La sintassi per creare una matrice è la seguente:
    tipoDiDati nomeMatrice [R][C];
    dove R è il numero delle righe, mentre C quello delle colonne

    La sintassi per operare con le matrici è analoga a quella vista per i vettori, con la differenza che per individuare un elemento della matrice ora sono necessari due indici.

    NOTE

    1 Unità di velocità di trasmissione in Telecomunicazioni.
    2 “stringa”, ‘carattere’
    3 Restituisce il primo (il più vecchio) carattere nel buffer, dopo di che lo rimuove; quando tutti i byte dei dati saranno stati letti, e quindi rimossi, il buffer sarà vuoto e Serial.available() restituirà il valore 0 (che in un test corrisponde a FALSO)
    4 Ignora eventuali caratteri iniziali che non siano cifre e la ricerca viene interrotta quando viene letto un un carattere che non rappresenti una cifra (o “.” nel caso di Serial.parseFloat()).
    5 Una stringa è una sequenza di caratteri come lettere, numeri e simboli.

  • 01 Incontro del 30-11-24

    Gli appunti dell’incontro del gruppo di approfondimento del linguaggio Python.

    Le liste

    La lista, o elenco, è un insieme ordinato di più elementi in un’unica variabile; essa vienecreata utilizzando le parentesi quadre; ad esempio:

    invitati = ['Giovanni', 'Michelangelo', 'Riccardo', 'Angelo']
    print(invitati)

    [‘Giovanni’, ‘Michelangelo’, ‘Riccardo’, ‘Angelo’]

    Le parentesi quadre indicano l’inizio e la fine della lista.

    È possibile creare una lista vuota, []

    Gli elementi della lista sono

    • ordinati,
      cioè gli elementi hanno un ordine definito e sono indicizzati (ognuno memorizzato per posizione)
    • modificabili,
      sono mutabili, cioè è possibile aggiungere o rimuovere elementi dopo che la lista è stata creata; se si aggiungono nuovi elementi, questi verranno posti alla fine della lista
    • consentono valori duplicati, ciò è possibile poiché gli elementi sono distinti per l’indice e non per il valore
    • possono essere di qualsiasi tipo di dati, anche un’altra lista1
    • non necessariamente omogenee; cioè possono essere anche di tipo diverso fra loro

    In Python le liste sono definite come oggetti di tipo list e possono essere passati come attributi di funzioni.

    Il ciclo for che abbiamo visto per le stringhe è applicabile anche alle liste.

    �Esercizio

    Scrivere una lista di numeri interi ed un programma che, con il ciclo for, sommi tutti i suoi elementi.

    Una possibile soluzione

    lista = [3, 6, 9, 12, 15]
    somma = 0
    for numero in lista:#per ciascun numero presente in lista
      somma += numero
    print(f"Il risultato della somma è {somma}")
    # print(sum(lista))

    �Esercizio

    Scrivere un programma che moltiplichi tra loro tutti gli elementi di una lista diversi da zero.

    Una possibile soluzione

    lista = [3, 6, 9, 12, 15]
    prodotto = 1
    for numero in lista:
      if numero != 0:
          prodotto *= numero
    print(f"Il risultato della moltiplicazione fra tutti gli elementi della lista è {prodotto}")

    �Esercizio

    Scrivere una funzione che, data una lista di numeri, disegni un istogramma orizzontale con il carattere speciale █ (FULL BLOCK)

    numeri = [3, 9, 6, 15]
    def istogramma(lista):
      for numero in lista:
        print("█" * numero)
        # print(chr(9608) * numero)
    istogramma(numeri)

    Risultato

    ███

    █████████

    ██████

    ███████████████

    � Esercizio

    Scrivere una lista di numeri interi ed un programma che, senza usare la funzione max(), ne visualizzi il più grande utilizzando il for e l’if.

    Una possibile soluzione

    numeri = [42, 9, 23, 11, 17, 56, 3]
    massimo = numeri[0]
    for numero in numeri:
      if numero > massimo:
        massimo = numero
    print(f"Il numero maggiore della lista {numeri} è: {massimo}")
    # print(max(numeri))

    Accesso agli elementi di una lista

    Proprio perché gli elementi della lista sono indicizzati, è possibile accedervi facendo riferimento al loro indice2; si tenga presente che il primo di essi ha indice 0 e non 1. All’uopo si fa uso dell’operatore porzione [ ] o slicing.

    Esempi:

    lista = ['Giovanni', 20, 'Riccardo', True]
    print(lista[2]) # terzo elemento della lista (1)
    print(lista[0:2]) # primo e secondo elemento della lista (2)
    print(lista[:2]) # primo e secondo elemento della lista (3)
    print(lista[1:4]) # secondo, terzo e quarto elemento (4)
    print(lista[1:]) # dal secondo all'ultimo elemento (5)
    print(lista[-1]) # dall'ultimo a ritroso (6)

    Risultati

    Riccardo # (1)

    [‘Giovanni’, 20] # (2)

    [‘Giovanni’, 20] # (3)

    [20, ‘Riccardo’, True] # (4)

    [20, ‘Riccardo’, True] # (5) True # (6)

    Dagli esempi si evince:

    • è possibile specificare un intervallo di indici indicandone l’inizio e la fine:il valore restituito sarà ancora una lista costituita dagli elementi individuati mediante gli indici
    • a differenza dell’elemento avente come indice il limite inferiore dell’intervallo il quale viene incluso nella nuova lista, l’elemento avente come indice l’estremo superiore viene escluso
    • se viene omesso il limite inferiore dell’intervallo, la nuova lista inizierà dal primo elemento, cioè quello di indice 0
    • se viene omesso il limite superiore dell’intervallo, la nuova lista inizierà dall’elemento avente per indice l’estremo inferiore e proseguirà fino all’ultimo elemento della lista
    • se si indicano indici negativi, la ricerca inizia dalla fine della lista
    • se si indica un intervallo con estremi negativi, in questo caso viene escluso l’elemento avente per indice l’estremo inferiore.

    Per controllare se Giovanni è presente nella lista degli invitati, si può ricorrere all’operatore booleano3 in; tre esempi:

    Esempio 1

    invitati = ['Giovanni', 'Michelangelo', 'Riccardo', 'Angelo']
    x = 'Giovanni' in invitati
    print(x)

    Risultato

    True

    Esempio 2

    invitati = ['Giovanni', 'Michelangelo', 'Riccardo', 'Angelo']
    if 'Giovanni' in invitati:
      print('Giovanni è nella lista degli invitati')

    Risultato:

    Giovanni è nella lista degli invitati

    Angelo G. ha proposto che sia l’utente a digitare l’elemento per il quale determinare l’appartenenza o meno alla lista con il seguente codice:

    invitati = ["Angelo","Federico","Giovanni","Marta"]
    x = input("E' tra gli invitati? ")
    if x in invitati:
      print(f"{x} è tra gli invitati")
    else:
      print(f"{x} non è tra gli invitati")

    Anche combinando not con in, è possibile sapere se un elemento non è contenuto nella lista:

    Esempio 3

    invitati = ['Giovanni', 'Michelangelo', 'Riccardo', 'Angelo']
    if 'Giuseppe' not in invitati:
      print('Giuseppe non è stato invitato')

    Risultato

    Giuseppe non è stato invitato

    E se si vuol sapere il numero degli elementi della lista? Basta usare la la funzione integrata len()

    invitati = ['Giovanni', 'Michelangelo', 'Riccardo', 'Angelo']
    print(len(invitati))

    Risultato

    4

    ______________________

    NOTE

    1 In tal caso si parla di lista annidata.

    2 Un indice può essere sia un numero intero, sia una espressione che produca un numero intero.

    3 Nel senso che restituisce vero o falso.

  • 01 Incontro del 9-11-24

    Appunti dell’incontro di approfondimento di Arduino UNO Rev 4

    Premessa

    1. Arduino viene programmato nell’ambiente di sviluppo open source Arduino IDE
    2. Salvo alcune eccezioni (le direttive, riconoscibili per la presenza di un #), le istruzioni per Arduino sono comandi
    3. Tutti i comandi terminano con un punto e virgola
    4. Il linguaggio di programmazione è il C
    5. Le formulazioni di alcune istruzioni sono state create proprio per esemplificare la programmazione di Arduino; se ne fa carico l’IDE di trasformarle in istruzioni del C
    6. Il linguaggio usato per Arduino può essere arricchito, mediante un insieme di file detto libreria, con nuove proprietà e funzioni specifiche per un determinato dispositivo
    7. L’arricchimento viene effettuato mediante la direttiva
      #include nomeLibreria.h
      la cosiddette inclusione della libreria
      Che sia una direttiva lo si capisce, come già detto, dalla presenza del simbolo # ; ricordiamo ancora una volta che per le direttive non è previsto il punto e virgola
    8. Se si usa una libreria, occorre specificare (nella modalità indicata dalla libreria stessa) il nome del dispositivo cui si potranno applicare le proprietà e le funzioni integrate
    9. Un programma, detto sketch, viene trasformato in un linguaggio comprensibile per Arduino prima di caricarlo su di esso. E ciò avviene in due fasi:
      1. La precompilazione in cui vengono eseguite le direttive; ad esempio sono inglobate nel programma tutte le proprietà e funzioni (dette metodi) messe a disposizione dalle librerie. In questa fase vengono anche inglobati quei comandi esemplificativi, creati apposta per la programmazione di Arduino e di cui si è detto in precedenza.
      2. La compilazione vera e propria, cioè la trasformazione del codice nei 0 e 1 che sono familiari per Arduino.
    10. Per utilizzare la scheda WiFi UNO R4 è necessario  installare il pacchetto di schede appropriato, a tal proposito può essere utile seguire passo passo le indicazioni su
      https://docs.arduino.cc/tutorials/uno-r4-wifi/r4-wifi-getting-started/

    Se nel selettore della schede dell’IDE di Arduino non compare la WiFi UNO R4, è necessario procedere alla installazione del pacchetto della scheda. Per far ciò, poiché fa parte del Core, apri “Gestione schede”

    • dal menu Strumenti, se usi la versione 1.8.19 dell’IDE
    • in alto a sinistra, se usi la versione 2.x dell’IDE

    cerca UNO R4 WiFi Boards ed installa la versione che desideri utilizzare, preferibilmente la più aggiornata.

    shermata1.png

    In File > Esempi sono presenti moltissimi esempi per questa scheda; casomai non fossero ancora presenti dopo l’installazione del pacchetto, chiudi e riavvia l’IDE. Ed è precariata con uno di questi, (MatrixIntro.ico) che la scheda viene venduta.

    Letture consigliate:

    Pillola informatica: le librerie

    Puoi potenziare il tuo Arduino aggiungendo alcune librerie, infatti esse sono insiemi di codici già scritti e testati che rendono più facile ed intuitivo l’utilizzo di sensori ed attuatori, l’uso del monitor seriale ed altro, rendendo disponibili nuove funzionalità. Alcune librerie sono già integrate nell’IDE, altre vanno aggiunte, altre installate: innumerevoli sono le librerie disponibili e scaricabili in internet.

    Nel programma in cui includiamo una libreria a volte è necessario effettuare la “richiesta”di convergere su di una variabile, detta oggetto, le nuove funzioni e capacità messe a disposizione della libreria stessa; la scelta del nome dell’oggetto, possibilmente esplicativo, spetta al progettista purché sia univoco.

    La direttiva:

    #include <Libreria.h> 1

    impartisce ad Arduino di utilizzare una libreria non integrata; essa va posta all’inizio del programma. Durante la compilazione l’IDE includerà nel firmware sia il nostro codice che quello delle librerie.

    Per prima cosa controlliamo se la nostra libreria è fra quelle già disponibili nell’IDE: andiamo alla voce di menu Sketch/#include libreria e verrà mostrato un elenco delle librerie già disponibili; se compare la libreria di cui abbiamo bisogno, basta cliccare su di essa perché il codice di inclusione venga aggiunto automaticamente al nostro programma.

    Se invece la libreria di cui abbiamo bisogno non dovesse comparire fra quelle già disponibili, controlliamo se è fra quelle che è possibile aggiungere dalla voce di menu Sketch / #include libreria / Gestione librerie: si aprirà una finestra con un elenco di librerie pronte per l’installazione; se vi compare la libreria cercata e viene mostrato un menu a discesa, scegliamo la versione della libreria e clicchiamo su Installa. Una volta che l’istallazione sarà terminata, comparirà la dicitura INSTALLED accanto al nome della libreria.

    Utilizzo della matrice LED integrata

    Per poter gestire la matrice di LED è necessario:

    1. includere la libreria Arduino_LED_Matrix
      #include <Arduino_LED_Matrix.h>
      Non è necessario installarla; è già incorporata!
    2. definire un oggetto con un nome di nostra scelta, ad es. matriceLED
      ArduinoLEDMatrix matriceLED;
      dove ArduinoLEDMatrix è il costruttore indicato dalla libreria
    3. inizializzare l’oggetto nel setup
      matriceLED.begin();

    Per cui, in definitiva, il codice di avvio sarà del tipo:

    #include <Arduino_LED_Matrix.h>

    ArduinoLEDMatrix matriceLED;

    void setup() {

    matriceLED.begin();

    }

    LivePreview

    Per prendere dimestichezza con la matrice è utile vedere in diretta cosa si può disegnare sulla matriceLED. Per far ciò è necessario far interagire Arduino e LED Matrix Editor2 esclusivamente attraverso il browser Google Chrome; si tratta di un software sperimentale in fase di pre-rilascio al m omento della stesura del presente tutorial, per cui non è escluso qualche problemino!

    2.png

    • Collega Arduino al computer tramite porta USB
    • Apri l’IDE di Arduino
    • Nel menu File / Esempi soffermati sulla sezione Esempi per Arduino WiFi R4 ed in particolare su LED_MATRIX, carica il programma LivePreview
    • Apri Google Croome all’idirizzo https://ledmatrix-editor.arduino.cc/
    • Nella schermata dell’Editor, clicca sull’icona del dischetto posta al centro in alto e segui le istruzioni, cioè:
      • conferma di aver caricato lo sketch
      • connetti il tuo dispositivo collegandoti alla porta USB accoppiata (accertati che non ci siano altre comunicazioni seriali attive)
      • Inizia a disegnare cliccando sugli elementi della matrice e vedrai accendere o spegnere i LED sulla MatriceLED

    Dobbiamo dar merito al piccolo Angelo D. che ha dato luogo ad una animazione in questo modo:

    • ha creato prima più fotogrammi di un pupazzetto in successione di varie posizioni;
    • ha cliccato sull’icola posta in alto al centro dell’editor per creare la successione dei fotogrammi;
    • poichè la permanenza di ogni fotogramma risultava ridottissima, ha duplicato più volte ogni singolo fotogramma per rallentarne il movimento.

     Sicuramente avrebbe agito diversamente se prima fosse stato informato che nella parte sottostante il singolo fotogramma compare il ritardo temporale prima di passare al fotogramma successivo; forse sarebbe stato meno creativo! 

    Durante le esercitazioni sono state riscontrate alcune difficoltà da parte di alcuni partecipanti; allorchè si scollegava l’Arduino UNO R4 e lo si ricollegava, veniva generata una diversa porta USB virtuale, ma nell’Editor l’Arduino risultava collegato alla porta precedente: in alcuni casi è bastato chiudere e riavviare l’Editor. Come detto l’Editor è in fase sperimentale!

    1<libreria> o “libreria” a seconda che la libreria si trovi nella cartella delle librerie di Arduino o nella cartella in cui è posizionato il codice del progetto.

    2https://labs.arduino.cc/en/labs/led-matrix in particolare la liberatoria in fondo alla pagina.

  • Il nuovo Arduino UNO R4 e l’esemplicazione nell’apprendimento del Coding

    Come già anticipato, sabato 9 nov 2024 partirà una nuova iniziativa in cui, grazie alle potenzialità dell’Arduino UNO R4, affronteremo il coding in un modo innovativo con metodi semplici grazie alla matriceLED integrata.

    Per motivi organizzativi è necessario prenotarsi; per chi non l’avesse già fatto è pregato di farlo.

    Info: WhatsApp 3286128138

    Di seguito il programma del primo modulo:

    Premessa 
    Pillola informatica: le librerie 
    Aggiungere una libreria 
    Utilizzo della matrice LED integrata 
    LivePreview 
    Pillola informatica: le variabili di tipo intere 
    Pillola Informatica: gli array 
    Array unidimensionale o vettore 
    Array bidimensionale o matrice 
    Creare una bitmap LED per LED 
    Lampeggio nei vertici della matrice 
    Esercitarsi con il FOR 
    Il ciclo FOR
    Illuminare gli elementi della terza riga della Matrice Led
    Esercitarsi con il WHILE 
    Esercitarsi con l’ IF 
    Pillola informatica 
    Istruzione condizionale if… else… 
    Una simpatica e semplice animazione 
    Carrellata dei fotogrammi disponibili nella libreria 
    Animazioni 
    Immagine che cambia durante l’esecuzione del programma 
    Animazione con due fotogrammi 
    Un cuore pulsante 
    Le animazioni nella libreria 
    Contatore a quattro cifre 
    Modifica del programma per inviare un numero intero da tastiera o sensore 
    Scrivere testo statico o scorrevole sulla matrice 
    Testo statico 
    Testo scorrevole prefissato
    Testo scorrevole digitato da tastiera
    I metodi della libreria ArduinoGraphics utilizzati nel codice
    Analog Plotter con la matrice a LED di Arduino
    GIOCHINO: un pixel che rimbalza sui bordi della matriceLED
    Pillola di Informatica: numeri casuali 
    API della libreria Arduino_LED_Matrix

  • Prossime attività

    Cari soci,

    alle 16.30 di sabato 9 novembre, presso la sede dell’associazione Puglia Software Open Source alla via Baldacchini di Barletta, avrà inizio il corso 

         “Il nuovo Arduino UNO R4” 

    Esso sarà rivolto ANCHE a principianti dai 10 anni in su e si articolerà in 3 fasi:
       – Semplici comandi e presentazione delle strutture di controllo  attraverso giochi di luce con la matrice LED di ARDUINO UNO R4
       – Esperienze con i vari sensori ed attuatori in dotazione all’Associazione
      – Domotica
    Naturalmente è inevitabile che le tre fasi si intreccino fra loro.

    Per ovvi motivi organizzativi la partecipazione, gratuita per i soci, sarà rivolta ad un numero ristretto di partecipanti, per cui è NECESSARIO PRENOTARSI: chi prima arriva, prima si calza!
    Sabato 16 novembre, sempre alle ore 16.30,  riprenderanno gli incontri su Python:

           “PYTHONando, Pensare da informatico senza esserlo”

    Si partirà dalla rappresentazione grafica, ed inevitabilmente sarà ristretto a chi già mastica un po’ di coding specifico, dando per scontata la conoscenza degli argomenti già trattati.

    Inoltre sono  previsti due incontri, non ancora calanderizzati, sull’ Intelligenza Artificiale. Vi terremo informati.

    Info:

    cell. 3286128138

    pugliasoftwareopensource@gmail.com