Profilo di nuzzopippo

Nome nuzzopippo
Indirizzo email nuzzopippo@gmail.com
AvatarAvatar utenti
Messaggi182
Firma forum
Fatti non foste a viver come bruti...
  • Punto di avvio di una applicazione modulare
    Forum >> Programmazione Python >> Scripting
    I miei saluti

    Nel corso del tempo ho preso l'abitudine di strutturare le mie applicazioni secondo una struttura da "modulo standard", articolata in sub-moduli specializzati per tipologia d'uso, giusto per esempio segue l'articolazione di una cosetta correntemente in saltuaria implementazione

    NzP:~$ tree
    .
    ├── lanmessage
    │   ├── gui
    │   │   ├── confgui.py
    │   │   ├── groupgui.py
    │   │   ├── __inity__.py
    │   │   ├── login.py
    │   │   ├── messagesgui.py
    │   │   ├── panels.py
    │   │   ├── pwdchanger.py
    │   │   └── winmain.py
    │   ├── __init__.py
    │   ├── starter.py
    │   ├── utility
    │   │   ├── __init__.py
    │   │   └── utility.py
    │   └── work
    │       ├── data_manager.py
    │       ├── __init__.py
    │       ├── linux_manager.py
    │       ├── notifiers.py
    │       └── windows_manager.py
    └── start.py
    
    4 directories, 18 files
    NzP:~$
    
    Tale tipo di implementazione da alcune "complicazioni" nello spazio dei nomi che malgrado abbia letto un po' di documentazione ed alcune PEP (tra cui la 420, che ho deciso di non utilizzare) non mi riesce di superare, probabilmente per mia incapacità di comprensione, confesso che spazio dei nomi ed uso dei files "__init__.py" mi confonde un po'.

    Dette complicazioni, essenzialmente, corrispondono alla circostanza che se utilizzo, per l'avvio della applicazione, un file interno alla struttura del pacchetto, l'assegnazione del "__main__" quale "nome" fa perdere allo stesso modulo lo spazio dei nomi del "pacchetto" ... mi spiego: supposto un file di inizializzazione (lanmessage.starter.py) della applicazione così composto:

    # -*- coding: utf-8 -*-
    
    # imports da libreria base
    import os
    
    # imports da virtual environment
    import appdirs
    
    # import locali
    from lanmessage.gui.winmain import WinMain
    
    
    def def_dirs() -> dict:
        '''
        Definisce le directory da utilizzarsi nella applicazione.
        Nella eventualità non esistano, le crea.
        '''
        app_name = 'lan_message'
        app_author = 'nuzzopippo'
        app_dirs = {}
        app_dirs['data'] = appdirs.user_data_dir(app_name, app_author)
        app_dirs['cache'] = appdirs.user_cache_dir(app_name, app_author)
        app_dirs['log'] = appdirs.user_log_dir(app_name, app_author)
        app_dirs['state'] = appdirs.user_state_dir(app_name, app_author)
        app_dirs['config'] = appdirs.user_config_dir(app_name, app_author)
        try:
            for key in app_dirs.keys():
                if not os.path.exists(app_dirskey) or not os.path.isdir(app_dirskey):
                    os.makedirs(app_dirskey)
        except OSError as e:
            print(repr(e))
            exit(1)
        return app_dirs
    
    
    def go() -> None:
        app_dirs = def_dirs()
        win = WinMain(app_dirs)
        win.mainloop()
    
    
    if __name__ == '__main__':
        go()
    
    
    Eseguendolo direttamente viene perso lo spazio dei nomi del modulo

    NzP:~$ source /home/nuzzopippo/venvs/tests_v/bin/activate
    (tests_v) NzP:~$ /home/nuzzopippo/venvs/tests_v/bin/python3.10 /home/nuzzopippo/
                     src/my_work/LanMessage/src/lanmessage/starter.py
    Traceback (most recent call last):
      File "/home/nuzzopippo/src/my_work/LanMessage/src/lanmessage/starter.py", line
           8, in <module>
        from lanmessage.gui.winmain import WinMain
    ModuleNotFoundError: No module named '\lanmessage'
    (tests_v) NzP:~$
    A ciò ovvio implementando un semplice punto di avvio (start.py) al di fuori del pacchetto applicativo, nrl caso in specie è così fatto:

    # -*- coding: utf-8 -*-
    
    from lanmessage import starter
    
    '''
    TODO
    
    DIRAMAZIONI X NOTIFICHE :
    
    Per Linux   : Studiare ed implementare notify2 - python-dbus
    Per Windows : Studiare ed implementare Windows-Toasts
    
    '''
    
    starter.go()
    Ora, tal modo di procedere, seppur funzionante non mi sembra "giusto", ogni tanto mi pongo il problema ma, come detto, non mi è riuscito, al momento, di trovare modalità altre ... la domanda è : è possibile utilizzare lanmessage.starter.py quale punto di avvio della applicazione conservando lo spazio dei nomi del modulo? Se si, come si può fare?




    Grazie dell'attenzione

    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    Ho inserito la riga da te menzionata e messa dentro il ciclo for() di adsrv, poi ho messo un print, ma non funziona.

    Ecco il codice così come l'ho modificato.
    Che ne pensi?

    Che ne penso? : che così non vai da nessuna parte!




    Gli esempi che Ti faccio sono, giust'appunto esempi per cercare di farTi intuire come funzionano le cose perché Tu possa indirizzarti per approfondire gli argomenti; se Ti limiti a copiincollare il codice non risolvi nulla.

    Ennesima esemplificazione :

    1° modifica nel Tuo codice la riga del bind inserita nel gruppo adsrv in questo modo :

    ...
                sc.set(0)
                sc.bind("<ButtonRelease>", self._on_sc_adsrv)       #bind 
                print(self._scales['adsrv'])                   #print
    ...
    
    2° inserisci dopo la funzione _on_open(self) questo codice :

        def _on_sc_adsrv(self, evt):
            ''' Stampa l'indice ed il valore dello scale del gtuppo "adsrv" manipolato. '''
            w = evt.widget
            try:
                index = self._scales['adsrv'].index(w)
                value = w.get()
                print(index, '=>', value)
            except ValueError as e:
                return            
    avrai così collegato a tutti i widget "scale" del gruppo "adsrv" (e solo a loro) una funzione di callback che al verificarsi dell'evento di rilascio del bottone sinistro del mouse su uno di loro individua lo scale interessato, ne estrae l'indice e stampa l'indice ed il valore assunto dallo scale.

    Spero che questo esempio Ti permetta di intuire come affrontare un evento e, approfondendo con la documentazione, di arrivare a gestirli.




    La documentazione che ho messo in link, pur se della versione precedente di tkinter, è quella secondo me più chiara esistente, troverai gli eventi al capitolo 54 ... purtroppo, temo che ciò che per me è chiaro possa non esserlo per retroterra diversi dal mio, credo Ti occorra un testo introduttivo, se sei anglodono forse potrebbe esserTi utile il testo "Python and Tkinter Programming (2000).pdf" mooolto datato ma di cui si trovano copie pirata in rete e, forse, versioni più aggiornate da acquistare.

    Se non sei anglofono, potrebbe esserTi utile un "work in progress", forse ora abbandonato, scritto da @RicPol (utente che non cesserò mai di ringraziare per l'enorme aiuto che mi ha dato) che verte sul framework wxpython ma i cui concetti di base si applicano più o meno a tutti gli ambianti grafici, con le ovvie differenze, si tratta di "Capire wxPython", è a pagamento ma dal costo irrisorio e secondo me vale la pena di leggerlo.




    Il consiglio che mi sento di darTi è di sospendere un attimo lo sviluppo che hai in corso e di studiare il funzionamento dei framework grafici, senza i concetti base non sarai in grado di progettare una tua applicazione (si, ci vuole un pogetto, prima di "fare")




    Ciao

    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    In che punto del codice devo mettere la riga sotto? Ho fatto delle prove ma ad ogni modifica della posizione dello slader la chiave non cambia, perchè?
    self._scales['adsrv'][1].get()
    
    

    Ovviamente, devi scrivere la riga indicata quando si verificano le condizioni perché venga letta ... le interfacce grafiche si basano sugli "eventi", a livello di codice bisogna gestire gli eventi quando si verifica un evento di interesse, cioè bisogna effettuare il così detto "binding" dell'evento collegando lo stesso evento ad un widget e ad una funzione di "callback" (cioè funzione di gestione dello evento).

    Se guardi nello esempio che Ti proposi due anni fa troverai due esempi di binding che collegavano le due categorie di strumenti ai relativi callback per aggiornamento dell'array di etichette li previsto


                sc.bind("<ButtonRelease>", self.on_struments)
    ...
                sc.bind("<ButtonRelease>", self.on_frequences)
    
    
    i metodi relativi Ti forniranno un possibile esempio di gestione.

    ... Naturalmente, quanto sopra è solo la punta dell'iceberc, diverse categorie di widget possono avere gestibili diverse categorie di eventi, possono anche gestire degli "eventi virtuali" specializzati

    ... insomma, si cade in quello che mi faceva anticipare come dubbia l'utilità di scriverti il codice funzionante, bisogna acquisire familiarità con gli eventi delle GUI per poter andare avanti, esistono moltissime varianti di approccio secondo ciò che vorresti e per la Tua problematica fare lo sai soltanto Tu, Ti è necessario affrontare la problematica approfonditamente, temo.




    Ciao







    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    Ho un problema: non riesco a capire qual'è il nome del dizionario per cui ad ogni modifica dello specifico slader mi permette di avere l'aggiornamento della specifica posizione.
    Riferisci al codice di "sintetizer2.py" che Ti ho postato prima? Lo ho già scritto, è il dizionario
            self._scales = {'adsrv': [],
                            'freqs': [],
                            'mixer': [],
                            'lfo1' : []}
    
    Le cui chiavi corrispondono ai "nomi" delle liste di etichette da Te definite
        adsrv = ['A', 'D', 'S', 'R','V',]
        freqs = ['1','2','3','4','5']
        mixer = ['1','2','3','4','5']
        lfo1 = ['lfo1']
    
    ed i cui valori sono liste di oggetti tkinter.Scale costruiti nello stesso ordine delle etichette da Te impostate, puoi accedere agli specifici scale per nome ed indice, come puoi constatare nei metodi "MainWin._on_save()" e "MainWin._on_save_as()"
    Ti preciso che, in quel codice, l'accesso ai valori degli scale avviene per i soli salvataggi o per il caricamento di dati già salvati, operazioni che vengono effettuate in cicli su chiavi del dizionario ed indici di lista corrispondente.
    Supposto il Tuo problema correntemente posto sia di accedere ad uno specifico elemento delle liste da Te impostate, p.e. l'elemento "D" della lista "adsrv", banalmente, dovrai accedere allo scale di indice "1" della chiave "adsrv" del dizionario "self._scales", tipicamente useresti:
    self._scales['adsrv'][1].get()
    self._scales['adsrv'][1].set(valore)
    per, rispettivamente, leggere ed impostare il valore corrente di detto specifico scale.

    Analogamente, i "modelli", una volata caricati, non sono altro che un dizionario con le medesime chiavi nelle cui liste sono contenuti i valori degli scale corrispondenti.

    In sostanza, banalmente, si opera con i metodi standard di dizionari e liste, niente di difficile imho.




    EDIT: corretti artefatti introdotti dall'editor dei post



    --- Ultima modifica di nuzzopippo in data 2024-06-18 06:10:44 ---
    Fatti non foste a viver come bruti...
  • Re: Tris
    Forum >> Programmazione Python >> Videogames
    L'errore
    \NameError: name 'letteraGiocatore' is not defined
    
    
    è quello che al momento blocca il Tuo script, questo errore è prodotto dalla circostanza che nel codice la funzione "letteraGiocatore()" è una funzione interna della funzione "disegna_tabella(tabella)", quindi NON È visibile nello spazio dei nomi del modulo.
    ... quando risolverai questo specifico problema, Ti si ripresenterà alla invocazione delle funzioni "chi_inizia()", "crea_copia_tabella(tabella)", etc ... tutte interne a disegna_tabella.

    Per il resto, non ho valutato l'insieme del codice però mi chiedo se sia Tuo e perché Tu lo stia scrivendo.

    La difficoltà da Te esposta tocca uno degli aspetti basilari di python, il che mi fa ritenere che Tu sia nuovo al linguaggio e consigliarTi la lettura almeno del capitolo 9.2 del tutorial (trovi il link nella sezione documentazione, vi è anche per la versione in italiano)




    EDIT: corretto il riferimento al capitolo, in precedenza era errato.




    --- Ultima modifica di nuzzopippo in data 2024-06-13 08:49:54 ---

    --- Ultima modifica di nuzzopippo in data 2024-06-13 08:50:28 ---
    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    Ok, allora Ti è sufficiente un esempio su come gestire tutti gli scale salvando le impostazioni fatte.

    Per dar seguito a quanto da Te esposto circa le Tue necessità, ho valutato opportuno l'utilizzo di dizionari, tanto per memorizzare i widget scale secondo chiavi relative

            self._scales = {'adsrv': [],
                            'freqs': [],
                            'mixer': [],
                            'lfo1' : []}
    
    
    Quanto per la memorizzazione delle impostazioni effettuate, popolate utilizzando analoghe chiavi.

    Per la serializzazione dei dati ritengo sia il caso di utilizzare json.


    L'esempio che Ti allego Ti permette di salvare dei "modelli" di frequenza in una sotto-directory che viene creata nella direttrice contenente lo script, ho conservato l'aspetto grafico, inserendo un menu approssimativamente analogo a quello che cercavi di fare Tu, ma la logica è completamente cambiata, quella da Te impostata non era idonea.

    I modelli salvati possono essere richiamati, allo scopo ho effettuato un sub-classamento di tlinter.simpledialog.Dialog che espone i soli nomi dei modelli memorizzati e permette di sceglierne uno, per poi modificarlo.

    Guarda il metodo "_on_open" di MainWin per avere un esempio di come leggere i dati da file, "_on_save" per vedere come memorizzare in liste, e quindi in dizionari, i valori impostati nei widget scale.




    Spero Ti sia utile, ciao



    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    Scusami ma ho avuto altro da fare in questi due anni oltre a studiare il linguaggio, abbi pazienza, ma non faccio ste cose per lavoro.

    Chiedo solo un aiuto.
    Non scusarti, comprendo benissimo, comunque, pur avendo realizzato alcuni programmi utilizzati sul lavoro per oltre vent'anni, neanche io programmo per lavoro, solo per divertimento.




    Se l'aiuto che chiedi è rendere quel Tuo codice "funzionale", chiarisci alcuni punti :

    1° - i tkinter.Scale dei pannelli "LF01 for FM (Hz)" e "Mixer (ohms x 10)" non presentano etichette, dovrebbero averle?, se si, come dovrebbero essere?;

    2° - le etichette, tra cui le "ADSRV" e "12345", andrebbero aggiornate con i valori dei rispondenti controlli scale?

    3° - cosa vorresti scaricare/caricare nel file in cui serializzi i dati?

    4° - perché due file python distinti, utilizzi due diverse applicazioni? perche? e cosa si aspetta di leggere la seconda applicazione?




    Rispondi a dette domande ed anche se credo che Ti servirà a ben poco vedrò di fornirti un codice funzionante.




    Se è altro l'aiuto che chiedi, specifica cosa.




    Ciao

    Fatti non foste a viver come bruti...
  • Re: Problema a estrapolare posizione slader in una variabile in tkinter
    Forum >> Programmazione Python >> GUI
    Ciao @Fabio75




    Non considerare quanto segue una critica, ma vedo che malgrado siano passati quasi due anni dal post qui concluso, i progressi da Te conseguiti nell'apprendimento del linguaggio sono stati insufficienti per renderTi operativo, tanto sotto il punto di vista OOP quanto riguardo il linguaggio python stesso, inoltre è evidente una macroscopica lacuna circa il funzionamento delle interfacce grafiche in genere, riferisco al tentativo di costruzione del menu :

    if __name__ == '__main__':
        #crea finestra
        app = MainWin()
        ...
        app.mainloop()
    
        #crea menu "File"
        menubar1 = tk.Menu(app, background = "black", fg="white") 
        filemenu1 = tk.Menu(menubar)
        filemenu1.add_command(label="Open")
        filemenu1.add_command(label="Save")
        menubar.add_cascade(label="LFO1 function", menu=filemenu1)
        app.config(menu=menubar1)
        app.config(menu=menubar)
        app.mainloop()
    In TUTTI i framework grafici, l'avvio delle finestre grafiche (il mainloop, per intenderci) avviene in un thread bloccante, ciò sta a significare che il codice che segue il mainloop non viene eseguito sin quando non di esce dal mainloop stesso, e nel momento che esci le finestre stesse cessano di esistere.

    Ciò puoi verificarlo con mano lanciando il Tuo codice, alla chiusura della finestra riceverai :

    Exception in Tkinter callback
    ...
    _tkinter.TclError: can't invoke "menu" command: application has been destroyed
    
    
    riguardo agli svariati errori per indice errato che ricevi quando provi ad utilizzare i widget "scale", purtroppo vi è una grave incomprensione del codice che a suo tempo Ti proposi, quel modello aveva sua ragion d'essere così come era, non può essere traslato (per altro con alcuni errori concettuali) nello scenario che cerchi di realizzare senza profonde modifiche.

    Ora, potrei anche manipolare il codice da Te proposto e postarTi un esempio funzionante ma credo sia inopportuno, Ti nasconderebbe ciò che avviene a livello di ragionamento e stesura del codice, confonderebbe le idee affrontare tutto in una volta, non Ti porterebbe a comprendere.

    Ti suggerirei di provare a realizzare l'esposizione dei valori per un singola singola coppia label/scale, poi due coppie ed, in fine passare ad articolazioni più complesse, penso che un tale studio potrebbe aiutarTi a comprendere come varia la problematica aumentando la complessità della GUI ed escogitare appropriate metodologie per affrontare le cose.




    Fermo restando che, se lo richiedi, sarei anche disposto a fartelo l'adattamento per rendere il Tuo codice funzionante, credo sia meglio per Te affrontare la problematica mediante lo studio sopra detto, si è comunque qua, se occorre.




    Ciao

    Fatti non foste a viver come bruti...
  • Re: Negozio
    Forum >> Principianti
    Lo avevo già visto e risolto i problemi esposti prima della mia risposta, mi chiedevo/chiedo però lo scopo di quel codice, suppongo sia un esercizio, in tal caso Ti avrei spiegato i punti critici e lasciato a te la soluzione ... dato che mi dici di eseguirlo, Ok, eccoti la soluzione, trova i Tuoi perché




    class VeganProducts:
        def __init__(self):
            self.products = {}  # Dictionary for storing products {product name: [quantity, purchase price, sale price]}
            self.sales = []  # List for recording sales [product name, quantity sold]
    
        def add_product(self, name, quantity, purchase_price, selling_price):
            if quantity < 0 or purchase_price < 0 or selling_price < 0:
                raise ValueError("The quantity, purchase price and selling price must be positive.")
    
            if name in self.products:
                self.products[name][0] += quantity
            else:
                self.products[name] = [quantity, purchase_price, selling_price]
    
        def list_products(self):
            print("Products available in the shop:")
            for name, details in self.products.items():
                print(f"{name}      {details[0]}        €{details[2]}")
    
        def register_sale(self):
            response = 'Y'
            vendita = []
            while response.upper() == 'Y':
                name = input("Enter the product name: ")
                quantity = int(input("Enter the available quantity: "))
                if name in self.products:
                    if self.products[name][0] >= quantity:
                        self.products[name][0] -= quantity
                        vendita.append([name, quantity])
                    else:
                        print(f'Quantità eccessiva, disponibile {self.products[name][0]}')
                else:
                    print(f'{name} : prodotto non disponibile.')
                response = input("Do you want to add a new product to sell? \n Press Y or N:   ")
    
            print('VENDITA REGISTRATA')
            total_price = 0
            for name, quantity in vendita:
                total_price += self.products[name][2] * quantity
                print(f"{quantity} X {name} : € {self.products[name][2]}")
            print(f"Totale € {total_price}")
            self.sales += vendita
    
        def show_profits(self):
            gross_profits = 0
            net_profits = 0
            for sale in self.sales:
                selling_price = self.products[sale[0]][2]
                costo = self.products[sale[0]][1]
                gross_profits += selling_price * sale[1]
                net_profits += selling_price * sale[1] - costo * sale[1]
            print(f"Gross profits: {gross_profits}")
            print(f"Net profits:: {net_profits}")
    
        def show_help_menu(self):
            print("Available commands:")
            print("1. Add product")
            print("2. Product list")
            print("3. Record sale")
            print("4. Help")
            print("5. Profits")
            print("0. Close")
    
        def exit(self):
            print("Exiting the program.")
            exit()
    
    def main():
        store = VeganProducts()
        store.show_help_menu()
        while True:
            choice = input("Enter the number corresponding to the desired action: ")
            if choice == "1":
                try:
                    name = input("Enter the product name: ")
                    quantity = int(input("Enter the available quantity: "))
                    purchase_price = float(input("Enter the purchase price: "))
                    selling_price = float(input("Enter the sales price: "))
                    store.add_product(name, quantity, purchase_price, selling_price)
                except ValueError as e:
                    print(e)
            elif choice == "2":
                store.list_products()
            elif choice == "3":
                store.register_sale()
            elif choice == "4":
                store.show_help_menu()
            elif choice == "5":
                store.show_profits()
            elif choice == "0":
                break
            else:
                print("Invalid choice. Try again.")
    
    if __name__ == "__main__":
        main()


    Fatti non foste a viver come bruti...
  • Re: Negozio
    Forum >> Principianti
    L'output da Te esposto NON PUÒ essere prodotto dal codice che hai allegato, quindi, che cosa stai effettivamente chiedendo?
    Fatti non foste a viver come bruti...