Profilo di RicPol

Nome RicPol
Indirizzo email ric.pol@libero.it
AvatarAvatar utenti
Messaggi72
Firma forum
https://pythoninwindows.blogspot.com/p/blog-page.html
Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: Sintassi ++ e --
    Forum >> Principianti
    Beh, se su questa app hai trovato proprio quel codice, allora vuol dire che è un altro dei numerosi strumenti che si possono buttar via senza problemi.


    Davvero, adesso non dico a te in specifico, parlo in generale.


    Ci sono molte sfumature e molte situazioni diverse. Uno può voler imparare Python, o no. Uno può *dover* imparare Python, o no. Uno può farlo per cazzeggio, un altro perché spera di farci eventualmente dei soldi. Uno può essere ricco di famiglia e con molto tempo a disposizione, un altro può essere un quarantenne squattrinato che lavora tutto il giorno e si ritaglia un po' di tempo la notte per studiare.


    Ma qualunque sia la vostra situazione, avete una cosa in comune: il vostro tempo ha un valore perché è una risorsa limitata. Può sembrare una spesa enorme investire 40 euro o giù di lì per comprarsi un buon libro, e può sembrare che se fai questa spesa poi sei costretto a leggerlo quel libro e a sudarci sopra perché altrimenti hai sprecato i tuoi soldi. E capisco che può essere sgradevole. Ma guardate che il tempo che perdete a seguire certi inqualificabili corsi su YouTube o certe folli "app magiche", quando lo convertite in soldi poi scoprite che è una spesa molto maggiore per un rendimento molto inferiore.


    Poi intendiamoci: non è che comprarsi un buon libro, o pagarsi un buon insegnante, va a sapere, sia di per sé garanzia di buona riuscita. Però certo almeno partite col piede giusto, e poi il resto è nelle vostre mani. Ma con tutta la buona volontà che uno può avere, se poi segue una "app" che mostra codice del genere, cosa mai potrà capire? Mah. Comunque, ciascuno si fa i suoi conti e le sue scelte, beninteso.




    --- Ultima modifica di RicPol in data 2018-10-16 11:53:00 ---

    --- Ultima modifica di RicPol in data 2018-10-16 11:53:14 ---
    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: ripulire lo script
    Forum >> Principianti
    Ma io non capisco proprio perché uno dovrebbe cercare su YT per cominciare... voglio dire, YT è notoriamente la cloaca della qualità su internet... boh.


    Comunque se """""l'insegnante""""" che hai trovato scrive davvero codice del genere, forse potresti lasciare un commento linkando a questo thread... è una goccia nell'oceano ma tanto vale...

    Per quanto riguarda libri, boh, in Italiano ovvio che non c'è molto. Ma probabilmente il migliore resta il Lutz https://learning-python.com/index-book-links.html#pubs e i suoi sono stati tradotti ("Imparare python" mi sembra che sia il titolo italiano; invece "programmare python" è più avanzato e non conviene all'inizio).




    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: Errore di lettura del file username.txt (hash sha3 512)
    Forum >> Programmazione Python >> Files e Directory
    Boh? Quel codice è una collezione di script scorrelati tra loro, e tra l'altro scritti malissimo in modo che non sarebbe neanche possibile importarli... tutta quella roba deve essere buttata e riscritta daccapo con un minimo di senso comune (niente codice a livello del modulo, per dire...). Non ho neanche idea di dove dovrei guardare per vedere un problema. Dovunque guardi vedo solo problemi, di tutti i tipi.


    Facciamo così: prima di tutto scorpora il codice che ti dà problemi, riducilo a un esempio concreto che faccia questo:
    1) crea il file partendo da nome e psw
    2) apre il file e verifica la psw.
    Tutto questo non dovrebbe richiedere più di venti/trenta righe. Così almeno cominciamo a vedere di che cosa stiamo parlando.


    Poi, non limitarti a descrivere in parole vaghe "che hai un errore". Quale errore? Dove? Posta lo stacktrace dell'errore, e vediamo.


    In ogni caso:
    > Per salvare le modifiche è necessario riavviare il programma
    > (Py non crea il file finché l programma non termina a quanto pare)
    Ma no, quando mai.

    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: ripulire lo script
    Forum >> Principianti
    Non ha senso scriverlo così, certo. Non ha neanche senso seguire qualcuno su YT che peraltro segue una guida elencata qui (che poi sarà il solito terribile pensare da informatico, ovviamente). Tanto vale seguire direttamente la guida, no? Ma in realtà tanto vale prendersi un buon libro e seguirlo con calma, passo passo.
    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: ripulire lo script
    Forum >> Principianti
    Il problema qui è in sostanza che non hai capito che cosa è una variabile e come funziona. Una variabile è solo un segnaposto per un oggetto (un riferimento, un puntatore... chiamalo come vuoi anche se ci sono nomi più precisi di altri). E' l'oggetto che contiene le informazioni, non la variabile. Una variabile non *può* contenere informazioni aggiuntive rispetto all'oggetto, perché semplicemente queste informazioni non sarebbero accessibili a Python. Naturalmente è comodo dare alla variabile un nome "significativo", ma il nome significativo è solo un promemoria per il programmatore, non è rilevante per Python. Quindi, se ci sono informazioni che non stanno nell'oggetto, non ci sono e basta. Il nome della variabile non c'entra nulla.


    Siccome tu non metti un'informazione essenziale (il nome del pilota) negli oggetti, il fatto che tu "sai" qual è il pilota guardando il nome della variabile non conta nulla perché non puoi dare questa informazione a Python, e quindi in sostanza non ci puoi fare nulla di utile. In pratica non esiste un modo in cui tu puoi *ricavare* il nome di un pilota, perché il nome non fa parte delle informazioni contenute dentro gli oggetti.


    Tutto il resto del tuo script (che contiene beninteso molti altri problemi separati) frana completamente come conseguenza del fatto che non hai capito come si usano le variabili. Per esempio, il fatto di dover scrivere compulsivamente "if name=='bottas': pilota(bottas)" etc. etc. per mille volte (che suppongo sia quello che speravi che ti avremmo consigliato come aggiustare) è una diretta conseguenza di questo problema. Se trovi il modo di capire bene come devono essere fatti i tuoi oggetti, e se capisci che cosa è una variabile e come si usa, vedi che trovi anche subito il modo di evitare quell'elenco infinito di "if".


    Oppure, se vuoi una cosa ancora più semplice: prova a completare questa banale funzione che restituisce il nome del pilota (eh, già) a partire dal suo numero di macchina:

    def cerca_pilota(num_macchina):
        for pilota in (bottas, hamilton, vettel, .......):
            if pilota[0] == num_macchina:
                return IL-NOME-DEL-PILOTA # che cosa diavolo e' "il nome del pilota" adesso???
        return 'nessun pilota con quel numero di macchina'
    
    Prova a costruire qualunque meccanismo che fa restituire il nome del pilota a quella funzione. Vedrai che non ci riesci, perché in definitiva Python non conosce i nomi dei piloti. L'unica cosa che puoi fare sarebbe... fare tu stesso il lavoro che dovrebbe fare Python:

    def cerca_pilota(num_macchina):
        if num_macchina == 77: # il numero di "bottas" (ma python non lo sa)
            return 'bottas'
        elif num_macchina == 44: # questo e' "hamilton", e NOI lo sappiamo!
            return 'hamilton'
        elif ......
            .......
        else:
            return 'nessun pilota con quel numero di macchina'
    
    Ma capisci che così non ha senso programmare, non ha senso neppure avere un computer. Il lavoro lo stai facendo tu.






    --- Ultima modifica di RicPol in data 2018-10-15 17:28:21 ---
    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: Sintassi ++ e --
    Forum >> Principianti
    Dove hai trovato quel codice? Quello è C, non Pyhton. In Python non esiste "++" come operatore, e "++a" è una noop (non fa nulla). Se vuoi incrementare di uno, in Pyton devi riassegnare: "a = a+1" oppure "a += 1" (perché "+=" esiste).


    Il resto del codice è Python, anche se non un Python molto intelligente, visto che il parametro "c" passato alla funzione non viene utilizzato. La funzione restituisce banalmente la somma dei parametri "a" e "b".



    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: memorizzazione immagini
    Forum >> Principianti
    OH ECCO!!! grazie, avevo cominciato a fare degli esperimenti ma non sapevo bene cosa escapare di preciso... buono a sapersi...




    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: memorizzazione immagini
    Forum >> Principianti
    Sai, il problema non è essere principianti (e ci mancherebbe). Il problema è essere principianti e voler fare cose da non-principianti. Il principiante impara che cosa è una lista python, per dire, e dice "ok, sono pronto: adesso faccio un'intelligenza artificiale che trasforma frasi italiane in azioni disegnate" (non scherzo, c'è davvero un thread del genere qui).


    Occorre andare per gradi, con calma e molta pazienza. E' ovvio che ti vengono in mente decine di applicazioni pratiche da fare "subito", ma non c'è niente da fare: dopo aver imparato la lista, impara il dizionario (per dire). In particolare, ogni cosa che riguarda una interfaccia grafica richiede nozioni di programmazione a oggetti. Sì, è vero che puoi abborracciare una finestra in tkinter così alla buona, un po' copiando in giro. Ma al primo ostacolo "da mondo reale" sei già in acque profonde. Naturalmente non è che uno debba leggersi tutto il GOF prima di affrontare la prima interfaccia grafica della sua vita, eh. Ma almeno avere un po' di dimestichezza con le variabili, le funzioni, le classi, i metodi.
    Tra l'altro, la spiegazione che ti ho dato è già molto semplificata e tagliata sul tuo caso specifico. In generale, il problema dei rapporti tra oggetti è una questione di design pattern complessa. Ma non è il forum la sede per imparare queste cose. Hai già visto quante parole ho dovuto metterci per spiegarti questa piccola questione.

    Purtroppo la tragica verità è che imparare a programmare è frustrante, non è divertente. O per lo meno, bisogna imparare a divertirsi con poco, per un bel po' di tempo. E' come un gioco di ruolo alle prime avventure: tu *sai* che è possibile castare magie del nono livello e andare a caccia di draghi, ma nel frattempo devi accontentarti di dare la caccia ai goblin e castare magic missile.





    > mi è venuto il dubbio se nel caso il modulo PIL abbia già qualche funzionalità nativà per tale scopo....
    Beh, certo che sì. Una volta che hai prodotto un oggetto PIL.Image caricandoci dentro un file immagine, puoi usare PIL.Image.filename per ri-ottenere il nome del file che ci hai caricato dentro: https://pillow.readthedocs.io/en/5.3.x/reference/Image.html#PIL.Image.filename (beh, certo: ovviamente quello *non* è l'oggetto-file, è solo la stringa-path del file... ma da quello hai comunque le informazioni necessarie per ri-aprire l'oggetto-file, se vuoi).



    --- Ultima modifica di RicPol in data 2018-10-13 09:42:38 ---
    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: memorizzazione immagini
    Forum >> Principianti
    Guarda, abbi pazienza ma è che proprio stai facendo un'insalata di concetti diversi. Confondi le cose, non sei preciso. Intanto liberati per prima cosa di quei "print". Non usare più "print", non pensare più a "print", lascia perdere "print". Questo "print" è una delle prime cose che i principianti imparano (o credono di imparare) ed è anche la singola cosa più dannosa che rovina la comprensione di un principiante. Non puoi confondere un riferimento a un oggetto con la stringa che l'oggetto emette in risposta a un __repr__() (e quindi a un print). Quella stringa non è un riferimento all'oggetto, è solo... decorazione, niente.


    Come seconda cosa, lascia perdere anche tkinter. Finché non hai chiaro che cos'è una variabile, che cos'è un oggetto, come si usano gli oggetti... non so, stai andando a tentoni invece di procedere per gradi. Per esempio, quando scrivi

    > img = [PhotoImage(file="a.gif"), PhotoImage(file="b.gif")]
    > (...)
    > come si nota in questo codice ho messo i files in una lista

    Ma no!, come si nota in questo codice hai messo in una lista *gli oggetti PhotoImage* che contengono i file, non i file. Siccome qui stiamo parlando di come risalire dal nome di un file agli oggetti e viceversa, confondere le due cose è parecchio grave, capisci. Eccetera eccetera.





    Ora ti spiego il problema se vuoi, ma il fatto è che temo che ti mancano le basi per comprendere quello che ti spiego. Quindi probabilmente crederai di aver capito, e continuerai ad andare a tentoni. Davvero, la soluzione è prendersi un buon libro e seguirlo daccapo passo-passo.


    In ogni caso, il problema è questo. Tu hai un oggetto-Risorsa, e poi un oggetto-Manager che "acquisisce" la Risorsa, diciamo così. In pratica, ciascuna Risorsa sta "dentro" il suo Manager. Il problema è:
    1) ho in mano un riferimento al Manager, voglio ricavare un riferimento alla Risorsa che contiene;
    2) viceversa, ho in mano una Risorsa, voglio sapere il Manager che la contiene.

    La prima parte del problema in genere è più semplice: si suppone che il Manager "sa" quale Risorsa sta gestendo, e quindi probabilmente ha anche un metodo già pronto per sputare fuori un riferimento alla risorsa. Se stai usano una classe-Manager scritta da altri (per esempio, all'interno di un framework come le tk) allora ti basta leggere la documentazione per trovare quel metodo (per esempio, abbiamo visto che esiste PhotoImage.cget). Se invece la classe te la stai facendo tu, allora ti conviene scrivertelo, un metodo del genere. Qualcosa come:


    class Manager:
        def __init__(self, risorsa):
            self.risorsa = risorsa
    
        def get_risorsa(self):
            return self.risorsa
    
    # uso:
    risorsa = 'io sono una Risorsa' # un qualunque oggetto-Risorsa
    manager = Manager(risorsa)      # un oggetto-Manager che "contiene" la Risorsa
    r = manager.get_risorsa() # restituisce un riferimento alla Risorsa usata
    r is risorsa # è True: il riferimento ottenuto è davvero quello alla Risorsa usata
    
    La seconda parte (risalire dalla Risorsa al Manager) è ovviamente più difficile. Se il Manager "sa" quale Risorsa contiene, viceversa la Risorsa esiste da prima che il suo Manager venga creato, e quindi non può "sapere" in quale Manager finirà. Ora, naturalmente se tu hai solo un Manager e una Risorsa, la soluzione è banale: ti basta mantenere in vita le variabili che si riferiscono a questi due oggetti (nell'esempio sopra "risorsa" e "manager"), e poi tu lo sai già che "quel" Manager contiene "quella" Risorsa.
    Ma se le cose diventano più "dinamiche", allora si complicano. In questi casi la soluzione è mantenere una struttura-dati parallela, una specie di registro dove annoti man mano quali Risorse sono contenute dentro quali Manager. Che cosa è questo "registro"? Mah, quello che vuoi, dipende dalle tue esigenze. Nei casi più semplici, un dizionario è la prima cosa che viene in mente, e in effetti può andar bene.


    Facciamo un esempio. Abbiamo una serie di Risorse, di cui non conosciamo neanche il numero esatto, perché le prendiamo da una sorgente esterna al nostro controllo (le carichiamo da un file preparato dall'utente, o da un database, va a sapere). Supponiamo, per capirci, che le nostre Risorse siano le righe di testo di un file esterno (ogni riga è una Risorsa). Quindi apriamo il file e carichiamo ogni riga in un oggetto-Manager (usiamo la classe Manager che ho scritto sopra):
    with open('file_delle_risorse', 'r') as f:
        for line in f:
            manager = Manager(line)
    
    Con un codice del genere abbiamo ovviamente due problemi: il primo è che non stiamo conservando *nessun* riferimento né ai Manager né alle Risorse. A ogni ciclo del "for", la variabile "line" si riferisce alla Risorsa, e "manager" si riferisce al Manager: ma al ciclo successivo, "line" e "manager" si riferiscono a una nuova Risorsa e a un nuovo Manager, e i precedenti diventano irraggiungibili e vengono distrutti. Quindi in pratica stiamo distruggendo il lavoro man mano che lo facciamo. Alla fine del ciclo, resteranno in vita solo l'ultima Risorsa e l'ultimo Manager creati. Del resto, non è che possiamo usare una variabile per ciascun Manager, come prima:
    manager1 = Manager(line1)
    manager2 = Manager(line2)
    ...
    
    perché semplicemente non sappiamo quante sono le linee del file, quindi quante sono le Risorse, quindi quanti sono i Manager da creare. Il secondo problema è quello che dicevamo: non sappiamo tener traccia dei collegamenti tra Manager e Risorse, e in particolare risalire da una Risorsa a un Manager (l'opposto è più facile, come abbiamo visto).
    Ed ecco che una struttura-dati separata (per esempio un dizionario) può risolvere entrambi i nostri problemi:
    registro = {}
    with open('file_delle_risorse', 'r') as f:
        for line in f:
            manager = Manager(line)
            registro\[line\] = manager    # scusa il \[ 
    
    In questo modo dentro il registro conserviamo i riferimenti sia alle Risorse (che sono le chiavi del dizionario) sia ai Manager (che sono i valori). Inoltre, conserviamo l'associazione Risorsa->Manager che ci interessa. Se per esempio abbiamo una Risorsa che si chiama "pippo", per risalire al Manager che la contiene basta fare:
    risorsa = 'pippo' # sappiamo che una delle risorse è "pippo"
    manager = registro\[risorsa\] # adesso "manager" è un riferimento al Manager di "pippo"
    # e viceversa...
    r = manager.get_risorsa() # ottengo dal Manager un riferimento alla Risorsa contenuta
    r is risorsa # è True
    
    Non è detto che un dizionario sia la struttura-dati migliore per contenere questo registro. Dipende dal caso specifico. Per esempio, se sei in un contesto in cui ti interessa di più *l'ordine* in cui ti arrivano le Risorse e quindi sono creati i Manager corrispondenti, allora potresti tenere una lista, o anche una doppia lista:
    registro_manager = []
    registro_risorse = []
    with open('file_delle_risorse', 'r') as f:
        for line in f:
            manager = Manager(line)
            registro_manager.append(manager)
            registro_risorse.append(line)
    
    E adesso, se la tua situazione è tale per cui ti interessa sapere qual è, poniamo, il terzo Manager e/o la terza Risorsa creata, puoi banalmente fare:
    terzo_manager = registro_manager[ 2 ]
    terza_risorsa = registro_risorse[ 2 ]
    
    E ci sono molte altre soluzioni possibili, a seconda di cosa conviene nei vari casi. E ovviamente tutte queste soluzioni hanno dei problemi e delle fragilità (che cosa succede se elimino un Manager, o se ne aggiungo uno? e se un Manager cambia Risorsa a run-time? eccetera). In generale, questo è un problema di implementare un pattern MCV: questo "registro", comunque tu lo realizzi, è in sostanza un "controller" che media tra gli oggetti presenti. In senso astratto, il controller è una classe (o una serie di classi) su cui deve essere possibile fare certe operazioni, e che devono garantire una certa robustezza. Per esempio, se volessi davvero implementare il tuo registro come una lista doppia, allora sicuramente tenere due liste "sciolte" nel codice è molto fragile: per esempio, se cancelli un Manager devi sempre ricordarti di cancellare anche la Risorsa corrispondente. Allora vorrai piuttosto "inscatolare" questa doppia lista in una classe specializzata che si curi di implementare in modo sicuro le operazioni richieste:
    class Registro:
        def __init__(self):
            self.registro_risorse = []
            self.registro_manager = []
        def aggiungi(self, manager, risorsa):
            self.registro_risorse.append(risorsa)
            self.registro_manager.append(manager)
        def elimina(self, n):
            self.registro_risorse.remove(n)
            self.registro_manager.remove(n)
        ... etc. etc. ...
    


    E poco per volta questo diventa un serio esercizio di programmazione a oggetti.


    PS: scusa l'uso di "\[" e "\]" per dire "[" e "]"... il fatto è che per qualche ragione questo autentico cess* di motore di rendering del forum si intestardisce a creare automaticamente voci inutili dell'inutile wiki.... immagino che nessuno riparerà più questo baco, ma è veramente una seccatura.






    --- Ultima modifica di RicPol in data 2018-10-12 15:44:22 ---
    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua
  • Re: Aggiornare il contenuto di un wxPanel
    Forum >> Programmazione Python >> GUI
    Mah guarda, in generale il problema che poni è interessante, solo che nel tuo caso particolare diventa tutto molto banale.


    In generale il problema è: come generare dinamicamente una parte della gui, e quali strategie usare per aggiornarla altrettanto dinamicamente. E qui in effetti si pone tutto il problema di MVC, bla bla bla. E, a seconda dei casi, può essere più conveniente una cosa, l'altra, l'altra ancora. Bla bla bla.


    Ma nel tuo caso specifico, che senso ha quello che stai cercando di fare? Per cominciare, wxPython ha *già* dei widget che visualizzano un calendario, e che fanno già tutto il lavoro per te. Se ben ricordo, ne aveva addirittura due. Usa quelli e vivi felice.


    In secondo luogo, se proprio vuoi farti un calendario a mano (magari per esercizio, non so), allora nel tuo caso ha poco senso complicarsi la vita. Semplicemente disegna 31 pulsanti e poi, a ogni cambio di mese, nascondi quelli che non ti servono. Così non hai bisogno di rifare il disegno, e tutto resta semplice. Come bonus di scaltrezza, puoi chiedere direttamente a python quanti giorni ha il mese che ti serve: così risolvi anche il problema degli anni bisestili, ed eviti di mettere sempre 28 giorni a Febbraio.


    Ecco una bozza di idea buttata giù in cinque minuti:


    import datetime
    import wx
    
    class CalendarPanel(wx.Panel):
        def __init__(self, parent, initial_date=None):
            wx.Panel.__init__(self, parent)
            if initial_date is None:
                initial_date = datetime.date.today()
            self.current_year = initial_date.year
            self.current_month = initial_date.month
            move_back = wx.Button(self, -1, '<')
            move_back.Bind(wx.EVT_BUTTON, self.on_move_back)
            move_forw = wx.Button(self, -1, '>')
            move_forw.Bind(wx.EVT_BUTTON, self.on_move_forw)
            self.display_date = wx.TextCtrl(self, style=wx.TE_READONLY)
            self.day_buttons = []
            for day in range(31):
                b = wx.Button(self, -1, str(day+1), size=(40, 40))
                b.Bind(wx.EVT_BUTTON, self.on_day_clic)
                self.day_buttons.append(b)
            self._refresh_display()
            self._refresh_day_buttons()
            siz1 = wx.BoxSizer(wx.HORIZONTAL)
            for widget in (move_back, self.display_date, move_forw):
                siz1.Add(widget, 0, wx.ALL, 5)
            siz2 = wx.GridSizer(7, 0, 0)
            for button in self.day_buttons:
                siz2.Add(button)
            s = wx.BoxSizer(wx.VERTICAL)
            s.Add(siz1)
            s.Add(siz2, 0, wx.ALL, 5)
            self.SetSizer(s)
    
        def _refresh_display(self):
            'Setta mese e anno attuali nella casella di testo.'
            display = '%i / %i' % (self.current_month, self.current_year)
            self.display_date.SetValue(display)
    
        def _refresh_day_buttons(self):
            "Reimposta i pulsanti per il mese corrente, nasconde i giorni in piu'."
            for button in self.day_buttons:
                button_day = int(button.GetLabel())
                try:
                    datetime.date(self.current_year, self.current_month, button_day)
                    button.Show()
                except ValueError:
                    # metodo brutale: se datetime.date non puo' essere formata, vuol dire
                    # che il mese attuale non ha quel giorno (es. 30 febbraio): 
                    # quindi semplicemente nascondo il pulsante.
                    # Nota che questo ha pure il vantaggio di tener conto dei bisestili!
                    button.Hide()
    
        def on_move_back(self, evt):
            self.current_month -= 1
            if self.current_month < 1:
                self.current_year -= 1
                self.current_month = 12
            self._refresh_display()
            self._refresh_day_buttons()
    
        def on_move_forw(self, evt):
            self.current_month += 1
            if self.current_month > 12:
                self.current_year += 1
                self.current_month = 1
            self._refresh_display()
            self._refresh_day_buttons()
    
        def on_day_clic(self, evt):
            button = evt.GetEventObject()
            button_day = int(button.GetLabel())
            date = datetime.date(self.current_year, self.current_month, button_day)
            print('hai cliccato', date)
    
    
    class MainFrame(wx.Frame):
        def __init__(self, *a, **k):
            wx.Frame.__init__(self, *a, **k)
            p = CalendarPanel(self)
    
    app = wx.App()
    MainFrame(None).Show()
    app.MainLoop()
    Naturalmente un vero calendario dovrebbe tenere i giorni incolonnati, e per questo c'è bisogno di un po' di lavoro in più. Dovresti farti una griglia di cinque settimane e poi, a ogni refresh del mese, non solo nascondi i giorni superflui, ma cambi proprio le label dei pulsanti. O meglio ancora, cambi le label dei pulsanti e non nascondi i pulsanti dei giorni superflui, ma li mostri come i giorni adiacenti del mese precedente e successivo. Come fanno i veri calendari, insomma.


    Ma allora, come dicevo... perché non usare un vero calendario, visto che wxPython ce l'ha?









    https://pythoninwindows.blogspot.com/p/blog-page.html
    Le mie guide: Come installare e usare Python su Windows - Progetti Python multilingua