Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Post - RicPol

Pagine: [1] 2 3 ... 222
1
Progetti e script / Re:Creare una Sitemap con python
« il: Gennaio 16, 2020, 15:22 »
è possibile, ma non è un esercizio affrontabile nei primi sei/otto mesi di apprendimento.

2
Database / Re: database sqlite aggiornare valori
« il: Gennaio 13, 2020, 21:40 »
Boh a parte che non si capisce niente di come ti esprimi... ma direi, discrimina nel callback a seconda di quello che vuoi fare.

Qui guarda che però si pone un problema a monte. Il prerequisito per scrivere un programma è imparare a programmare. I post su un forum non possono sostituire un corso di programmazione. Si scrive su un forum per chiedere dritte su tecniche particolari, cose così.

Quindi la vera domanda è: quale libro di programmazione stai seguendo passo-passo in questo momento, esattamente? E dove sei arrivato?

3
Tkinter / Re:Apertura finestre tkinter
« il: Gennaio 09, 2020, 19:36 »

4
Prima di tutto, i type hints non hanno effetto in Python. Se aggiungono confusione (e mi sembra questo il caso) basta non usarli... Se stai imparando observer, meglio imparare observer e non anche i type hints. Tra l'altro, onestamente usare i type hints con python < 3.7 è un po' un calvario (non che poi invece diventa un pacchia).

Dopo di che, effettivamente al momento i type hints non hanno lazy evaluation, quindi effettivamente se annoti usando un tipo prima di averlo dichiarato, hai il solito problema che avresti con la normale procedura di valutazione degli oggetti in Python. In effetti pare che in futuro (python 4) ci sarà questa benedetta lazy evaluation e già fin d'ora (python 3.7) si può usare con un __future__ import.
Quindi la soluzione giusta sarebbe passare a python 3.7 o meglio 3.8.

Dopo di che, siccome (ripeto) i type hints non servono a niente dal punto di vista dell'interprete Python, sono in pratica solo una (barocca) convenzione a uso e consumo di pacchetti esterni come MyPy... E guarda caso MyPy (ma credo anche gli altri type checker) ti consentono tranquillamente di risolvere questi problemi usando il *nome* del tuo tipo come stringa, invece che il tipo vero e proprio.
Quindi, se fai

>>> class Foo:
            def foo(self, bar: Bar) -> None:
                pass

NameError: name 'Bar' is not defined

Ma se invece fai:

>>> class Foo:
            def foo(self, bar: "Bar") -> None:
                pass

questo ovviamente a Python andrà benissimo, e MyPy capisce lo stesso che cosa vuoi dire, facendo un po' di dark magic "alla django" dietro le quinte.

5
A costo di sembrare un bot, qui tocca attaccarci il solito disclaimer standard:

Non è ancora stata trovata una scorciatoia per programmare eliminando la necessità di imparare a programmare. E non è ancora stato trovato un modo per imparare a programmare scrivendo codice alla come-viene-viene puntando a risolvere un problema specifico. Il consiglio è sempre di procurarsi un buon libro (e il Lutz è sempre la scommessa sicura) e seguirlo passo-passo dedicandoci tempo e concentrazione.

Ora, anche se un gestionale con le classiche operazioni CRUD è una delle tipologie di software più tipiche, perfino noiose da implementare, resta però un tipo di architettura complesso, che richiede una conoscenza non superficiale di molti differenti concetti, e l'uso di parecchie tecniche di programmazione. Non è una di quelle cose che basta girare su internet a "prendere spunto".
Per dire, solo questo thread è già lungo 13 post (14 con questo), e mi sembra che stia cercando di avvicinarsi vagamente al concetto di ORM. Ora, uno potrebbe decidere di affidarsi a un ORM (boh, Sqlalchemy per dire) oppure potrebbe anche decidere di scriversi un simil-ORM "ad-hoc" fatto in casa... o anche prendere un'altra strada diversa... ma sia come sia, non si può non porsi il problema della relazione che esiste, in questi scenari, tra un oggetto Python e una riga in una tabella (o in più tabelle con join) di un database. E per questo, come si modella in questi scenari un oggetto Python e come lo si fa corrispondere a qualcosa che fisicamente poi sta dentro un database. E per questo serve sapere come funzionano le classi in Python, e come funzionano i database.
E tutto questo, naturalmente, è solo uno dei molti aspetti (il Model, per dirla in gergo) che bisogna pianificare in un tipico relazionale di questo tipo. Poi ovviamente ce ne sono un bel po' di altri.
Ora, l'OP mi perdoni la franchezza ma... è senz'altro possibile che continuando ad agitare un secchio di bulloni abbastanza a lungo, ne venga fuori un aereoplano... non tratterrei il respiro nell'attesa, però.

6
Videogame / Re:grafica per campo minato URGENTE
« il: Gennaio 06, 2020, 17:40 »
URGENTE
Qual è di preciso la parte del manuale di Pygame che non ti è chiara?
URGENTE

7
Tendenzialmente puoi mettere l'operazione bloccante in un thread di esecuzione separato, e... fare qualcosa nel thread principale... "che cosa", dipende dalla natura del tuo compito. Nel caso più semplice ti disinteressi completamente del lavoro in background sull'altro thread, e ti limiti a dire "attendere prego..." con una piccola animazione che dà almeno l'impressione che il sistema non sia bloccato. Altrimenti, periodicamente fai in modo che il thread secondario segnali a che punto è arrivato, e lo visualizzi nella gui. Questo però dipende dal tipo di compito... talvolta è più facile farlo, talvolta meno.

Se poi il tuo compito è facilmente "spezzettabile" in parti separate, allora potresti anche restare in un solo thread, e aggiornare l'utente man mano che le varie parti vengono eseguite...

> tkinter è un processo a thread unico bloccante, non ci scommetterei sulla possibilità di implementarci il multithreading

Beh sì, tutti i GUI framework sono single-threading... ma questa è un po' la natura delle cose, visto che su tutti i sistemi operativi le primitive di disegno della GUI non sono thread-safe... in genere però è senz'altro possibile scrivere un programma multi-threading con GUI, perché no? Di solito l'accorgimento necessario è quello di non modificare direttamente la GUI dal thread secondario (ovvero, quello del mainloop), ma di postare nella coda degli eventi del mainloop l'azione che modifica la GUI. Questo perché il mainloop è (tipicamente) thread-safe rispetto alle azioni che modificano la GUI. In pratica il mainloop di un GUI framework è una "guaina" protettiva thread-safe intorno a primitive del s.o. che non sono intrinsecamente thread-safe.
Ora, va bene che le Tk sono un GUI framework giocattolo, ma non posso credere che non abbiano un mailoop thread-safe... Voglio dire... cavolo!... Non ho tempo di fare una ricerca adesso, ma direi che una googlata "tkinter threading python" o qualcosa del genere dovrebbe restituire degli esempi...

> col multiprocessing potresti realizzare qualcosa del genere

avrebbe lo stesso problema di base del multi-threading... non puoi modificare direttamente la GUI da qualcosa che non sia il thread principale del mainloop.

>  con framework più evoluti tipo le QT o le WX

Ovviamente sì... (modalità pubblicità sfacciata) nel mio libro dedico molte pagine a illustrare diverse tecniche per fare appunto cose del genere con le wx. (fine pubblicità) Ma ripeto, non posso credere che cose del genere non si possano fare con Tkinter, anche se non mi è mai interessato approfondire il problema (e posso dire con tranquillità che continuerà a non interessarmi neanche nel 2020).

8
+1

9
Videogame / Re:campo minato con python URGENTE
« il: Gennaio 03, 2020, 16:37 »
No però "global" no, eh?... che ce ne sono già abbastanza di problemi nel mondo.

I casi sono due...
1) l'OP impara a usare le classi,
2) oppure impara che le funzioni non sono semplicemente del codice rientrato di 4 spazi così per bellezza, ma hanno anche la possibilità di restituire un valore di ritorno, che a sua volta può essere passato come parametro in ingresso ad altre funzioni.

Tendenzialmente la soluzione "giusta" sarebbe la 1, anche se la 2 è ugualmente possibile e comunque andrebbe capita.
In linea di principio, quando hai un "coso" il cui stato può essere modificato da successive manipolazioni, e di cui quindi ti interessa conservare lo stato man mano che il "coso" viene manipolato, allora una classe è di solito il modo più naturale per modellare il "coso".
Quando invece hai un "coso" di cui non ti interessa conservare lo stato, ma che è invece "usa-e-getta" (stateless, come si dice in gergo), ovvero è un "coso" che prende (eventualmente) dei valori, li manipola in un certo modo e sputa fuori un risultato, e tutto quello che ti serve è il risultato, perché tanto poi la prossima manipolazione partirà comunque da altri valori e avrà un risultato diverso, ecco allora una funzione di solito è il modo giusto per modellare il "coso".

Detto questo, in certi casi è senz'altro possibile avere un "coso-con-stato" e modellarlo senza usare le classi, ma solo con le funzioni. Semplicemente, ogni manipolazione corrisponde a una funzione che accetta in ingresso il "coso", e sputa fuori una nuova versione del "coso" opportunamente manipolato, che a sua volta può essere passata in ingresso alla successiva funzione, per la successiva manipolazione. E' una strategia che si può usare con profitto in certi casi, soprattutto quando non ci sono side-effect da considerare.

(Detto questo: in primo luogo mi accerterei che l'OP abbia mai incontrato nella sua vita "return". Comunque, niente "global", mai, per principio).

10
Database / Re:sqlite3.OperationalError: no such table: snake
« il: Gennaio 01, 2020, 22:47 »
Questo però è un modo per *evitare* il problema, non per *capirlo* e quindi *risolverlo*. Tutto bene, eh? Finché non ti trovi a sbattere la prossima volta contro lo stesso problema... e allora, nuovo post...

11
Di per sé il codice gira anche sotto Linux...
Il problema, come ho scritto nella documentazione, è che il processo di pacchettizzazione richiede *anche* di far girare (con subprocess) il Python "target" (quello della distribuzione) un po' di volte... e siccome il Python "target" ovviamente è un eseguibile Windows, su Linux col cavolo che gira...

Questo in realtà è un problema *molto* fastidioso perché appunto, mi piacerebbe che WinPackIt potesse aiutare anche gli sviluppatori Linux che scrivono un programma e vogliono distribuirlo a un utente Windows, senza essere costretti a strani magheggi di cross-compilazione.

Adesso il prossimo passaggio (che porterà alla versione "finale" 1.0) è appunto quello di aggiungere un'opzione per una "delayed build"... in pratica, WinPackIt produce una build che contiene solo Python e i file del tuo progetto... ma niente dependency, e niente di tutto quello che richiederebbe di far girare il Python target sulla tua macchina. Invece sarà l'utente a completare l'installazione, facendo doppio clic su "install.bat"... questo scaricherà le dependency necessarie, e farà tutte le operazioni direttamente sulla macchina dell'utente.
Ovviamente questo è più pericoloso, perché se qualcosa va storto, va storto sulla macchina dell'utente e tu non hai possibilità di rimediare... Ma è anche l'unico modo per usare WinPackIt in modo completo anche su Linux.

12
Database / Re:sqlite3.OperationalError: no such table: snake
« il: Dicembre 30, 2019, 11:43 »
Guarda, il tuo codice è... un po' lungo, diciamo... e non ha comunque molto a che vedere con la natura del tuo problema. Certamente, imparare a organizzare il codice meglio e isolare le parti differenti ti aiuterebbe anche a rintracciare l'origine di problemi come questo, ma... sarà per un'altra volta...
Ora, non è che ci sia molto da dire: SE non c'è niente che non va nel pezzo di codice che crea il database (e sembra che non ci sia in effetti nulla di sbagliato, ma controllerei due volte per prudenza), ALLORA può succedere una delle due cose:
1) Se si tratta dello STESSO script che prima crea il database e poi lo utilizza (non è molto chiaro da quello che scrivi), allora può darsi che per qualche ragione il tuo codice chiama una funzione che accede al database PRIMA di chiamare la funzione che crea il database... Purtroppo qui Sqlite ha un comportamento molto sbrigativo... anche se il database in quel momento non esiste ancora, lui non si fa problemi e lo crea al volo. Poi però ovviamente dentro non ci trova la tabella che dovrebbe esserci, e allora crash crash crash.
2) Se invece tu crei il database con uno script differente, e poi fai girare il tuo programma "vero" che usa il database creato in precedenza, allora tieni presente che quando scrivi "connect(snake.db)" usando una path *relativa* (e fai bene a usare una path relativa, ci mancherebbe), la path che usi è relativa alla *directory corrente* che passi allo script al momento di eseguirlo, non alla directory del modulo dello script. Se usi i due script (quello che crea il db e quello che poi vi accede) in tempi diversi con diverse directory correnti... ovviamente la path relativa all'interno non verrà risolta allo stesso modo.

13
Ho terminato (per ora) un progettino natalizio: WinPackIt, il modo facile (o quasi facile) per realizzare distribuzioni stand-alone di programmi Python su Windows.

Tutto parte da un suggerimento che avevo scritto sul mio blog, di usare le distribuzioni "embeddable" di Python per Windows, per realizzare degli ambienti "chiusi" tipo virtual environment in cui installare pip, i pacchetti esterni necessari e i file del programma Python che ci interessa distribuire. Adesso ho messo insieme uno script che automatizza la procedura, producendo automaticamente delle "build" pronte da distribuire all'utente finale.

Lo trovate su PyPI https://pypi.org/project/WinPackIt/ (quindi potete installarlo con pip), il sorgente su GitHub https://github.com/ricpol/winpackit, e la documentazione (pure in Italiano! https://github.com/ricpol/winpackit/blob/master/docs_ITA.rst che è tradotta dall'inglese quindi fa un po' schifo... cioè, non che l'inglese sia proprio scott fitzgerald ma insomma).
Su mio blog https://pythoninwindows.blogspot.com/2019/12/winpackit-il-modo-facile-per.html trovate qualche riga di presentazione in più.

Fatemi sapere... soprattutto segnalatemi i bachi... che ce ne saranno un bel po'...

14
Base / Re:Salvare Variabili con Pickle dentro for loop
« il: Dicembre 24, 2019, 12:33 »
> suggerirei, se possibile, di acquisire, con calma, le basi del linguaggio e poi approfondire il contesto di interesse, poi ri-valutare il problema

Sì, questo è decisamente il consiglio giusto.
Dimenticare il tuo problema specifico per almeno sei mesi (meglio un anno) e seguire nel frattempo un buon libro passo-passo (il Lutz è sempre una buona idea). Ovviamente questa è anche l'unica idea che *nessun* principiante prende neanche lontanamente in considerazione, ci mancherebbe. Però è anche l'unica buona idea, quindi per ragioni etiche bisogna sempre, tutte le volte, almeno metterla a verbale.

Quello che stai cercando di fare non ha senso sotto praticamente nessun aspetto che mi venga in mente.
Il problema di partenza "voglio fare un programma con un sensore, ma adesso non ho un sensore fisicamente disponibile, quindi voglio simularlo" di per sé è assolutamente valido, ci mancherebbe. Però da qui in poi, frana tutto.
Per prima cosa: un sensore è un aggeggio che tipicamente invia dei dati su una porta predefinita. Non è "dalla stessa parte" del tuo programma. E' un *altro* programma, *separato* dal tuo, che gira in continuazione *indipendentemente* dal tuo (magari sulla stessa macchina e stesso sistema operativo, magari anche su una macchina diversa usando un web socket... ma non facciamo troppe distinzioni). Quindi, se la tua intenzione è quella di simulare la ricezione dei dati che emetterebbe un sensore, non ha nessun senso scrivere un programmino che si genera da solo i suoi dati e se li consuma... in qualunque modo tu faccia, con un ciclo infinito, con "count", con "range"... non ha nessun senso perché se avessi davvero un sensore, quello starebbe comunque *fuori* dal tuo programma e non dentro. Quello che dovresti fare è scrivere un programmino "server" che genera periodicamente dei dati e li scrive su un socket, poniamo, e va avanti così all'infinito. E poi, dall'altra parte, scrivere il "tuo" programmino, che ascolta quel socket all'infinito e, man mano che arrivano i dati, li processa in qualche modo.
Ora, naturalmente al limite questo potrebbe anche essere fatto con "un solo" programma multithreading o (meglio, visto il tipo di aggeggio che stai andando a simulare) multiprocessing. Ma in ogni caso si tratta di *due* processi (o almeno thread di esecuzione) distinti, non di uno solo. (Mi rendo conto che tutto questo è un po' arabo... ma è per farti capire che il consiglio-che-nessun-principiante-segue è anche il consiglio giusto... non ci sono scorciatoie).

Poi, in seconda battuta, dovresti capire che cosa vuoi farci davvero, con questi dati. Qual è la logica di processamento. Questo però non è nemmeno un problema di programmazione o di sapere Python... questo è proprio solo un problema di capire che cosa si vuol fare. Un sensore, tipicamente, emette dati virtualmente all'infinito. La tua logica non può essere "li raccolgo tutti e... <faccio qualcosa>" perché per definizione non *puoi* raccoglierli tutti... sono infiniti, capisci? Invece, puoi farci il tipo di operazioni che di solito si fanno con un flusso di dati infinito... ma devi decidere tu. Per esempio, può avere senso "scriverli in un file" (a parte l'uso di pickle che invece potrebbe o no avere senso... probabilmente no, ma lasciamo stare... stai usando strumenti a casaccio raccattati in giro...). Ma allora dovresti per esempio tenere il file aperto e accodarli man mano che arrivano... o magari decidi che ne raccogli un tot in un "buffer" (una lista, va a sapere) e li scrivi tutti di colpo (diciamo, 100 per volta). Ma in ogni caso devi attrezzarti per gestire un numero infinito di dati in arrivo.
Questo, ripeto, è un problema di logica prima ancora che di programmazione. Non è troppo difficile arrivare a scrivere un programmino che ha un thread "producer" che, diciamo, mette a intervalli regolari dei numeri in una Queue, e un thread "consumer" che a intervalli regolari legge e svuota la Queue. Questa è la meccanica di base, e se vuoi è già una simulazione "decente" (in realtà... boh, quasi) della meccanica del tuo sensore. Dopo di che, tuttavia, il tuo "consumer" si ritrova con un un ciclo eterno del tipo

def consumer(queue):
    while True:
        item = queue.get()
        if item:
            process_item(item) # <---- e QUI STA IL PUNTO
        queue.task_done()

E mi rendo conto che questo per te è di nuovo arabo (ma come dicevo, non ci sono scorciatoie) ma il punto è che devi capire che cosa fa, tutte le volte, "process_item" considerando il fatto che potrebbe essere chiamata un numero infinito di volte. Qui ti si aprirebbero altri problemi tecnici, ovviamente (per esempio: che cosa succede se "process_item", che è bloccante, impiega un tempo lungo? posso permettermi di bloccare la coda nel frattempo, oppure ho bisogno di "processamento in tempo reale"? Allora devi impostare un meccanismo asincrono dietro a questo, etc.).
Ma prima di tutto i problemi sono di tipo logico, non tecnico. Al limite potresti anche pensare di "simulare" (malissimo) i tuoi dati infiniti "nello stesso processo", senza ricorrere a niente della meccanica che davvero ti serve (processi separati, bla bla bla), un po' come stavi tentanto di fare... Basta usare un ciclo while True infinito come ti è stato mostrato, senza passare per itertools.count che non aggiunge niente di interessante.

def counsumer():
    while True:
        item = random.randint(1, 100) # per dire
        process_item(item)

def process_item(item):
    pass # <------- e qui sta il punto

consumer()

Qui "consumer" è solo la meccanica della produzione di dati (implementata malissimo, ma tant'è). Il problema però è la logica che vuoi mettere dentro "process_item", che deve trattare con un flusso di dati infinito.

15
Tkinter / Re:visualizzare dati intabellati
« il: Dicembre 22, 2019, 13:15 »
assolutamente no, non è il caso di complessificare, non ti serve quella roba per implementare un meccanismo di mcv... piuttosto, in genere ti serve un observer, che di solito viene introdotto subito prima di mcv nei manuali, per quanto ne so.

Pagine: [1] 2 3 ... 222