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 ... 225
1
Altri linguaggi / Re:Delucidazioni cython
« il: Febbraio 23, 2020, 22:10 »
Mah... la nebbia si fa sempre più fitta.
Guarda che un interprete CPython è un programma scritto in C. Quando tu fai girare uno script Python, quello che succede veramente è che fai girare un programma in C. Se hai una "struttura hardware particolare" (eh? che vuol dire poi? mah?) su cui non puoi far girare CPython, immagino che tu non possa neanche farci girare sopra un programma in C che scriveresti. Poi certo, ci sono casi in cui non vuoi/puoi installare tutto Python perché occupa troppo spazio, per dire... esistono soluzioni tipo MicroPython per questo... Non so, mi faresti un esempio di "struttura hardware particolare" che intendi?
Detto questo, uhm... suppongo che potresti provare Nuitka... non l'ho mai usato ma è un compilatore, pare che funzioni, e dovrebbe essere una cosa più simile a quella che stai cercando (se ho capito). Nota comunque che, partendo da CPython, compila con gli stessi compilatori che vengono usati per compilare CPython...
Inoltre non so che cosa tu intendi per "programmazione di basso livello", ma certamente non puoi metterti, per dire, a gestire la memoria mano (malloc etc) con Python... e quindi neanche con Nuitka o soluzioni del genere.

Scusa la franchezza, ma... devo chiedertelo: il tuo problema è che vuoi scrivere un programma in C? Perché in questo caso, mi sa che studiare C è un po' l'unica soluzione.

2
Altri linguaggi / Re:Delucidazioni cython
« il: Febbraio 22, 2020, 22:42 »
continuo a non capire, ma ti faccio notare che python e c++ sono entrambi linguaggi turing-complete, quindi tutto quello che puoi fare con uno in linea di principio puoi farlo con l'altro. Comunque sì, è necessario "per forza" l'interprete... è Python. Se non vuoi Python, puoi scrivere direttamente in C immagino... ma continuo a non capire che cosa vuoi fare e che cosa vuoi sapere. In ogni caso, davvero, la documentazione di Cython è piuttosto chiara, e basta provare per vedere che cosa può fare...

3
Altri linguaggi / Re:Delucidazioni cython
« il: Febbraio 22, 2020, 19:28 »
Mah, non mi è chiaro che cosa non ti è chiaro. La seconda parte del tuo post poi mi è assolutamente incomprensibile anche proprio dal punto di vista della sintassi italiana.
Comunque sì, Cython è sia un linguaggio (un superset di Python: non copre proprio tutto python, però... ma ci manca poco) sia un compilatore che produce estensioni C dal codice Cython e/o rende facile linkare librerie esistenti in C/C++ da dentro il codice Cython.
Ci si può fare tutto quello che ci si può fare con il "normale" Python... anzi in un certo senso ci si "deve" fare tutto quello che si fa con Python perché comunque per far girare delle estensioni Cython ci vuole pur sempre un interprete Python funzionante, che importa quelle estensioni... Quindi direi che qualunque piattaforma su cui puoi installare un "normale" CPython, puoi anche farci girare un tuo programma che ha estensioni scritte in Cython.

Comunque non è difficile provarlo per vedere che cosa puoi farci... la documentazione è chiara (se conosci un po' di C, altrimenti ti perdi il contesto) e i tutorial sono affrontabili.

4
Base / Re:Consigli su pianificatori/email
« il: Febbraio 20, 2020, 19:44 »
in genere queste cose sono un compito del sistema operativo... un cron job tipicamente.
Ho visto librerie di scheduling in python, ma classicamente queste cose si fanno con cron (o task scheduler in windows)

5
Base / Re:gestire Errore con while loop senza uscire
« il: Febbraio 19, 2020, 23:49 »
> potesse essere utile per un tentativo di ripristino semi-automatizzato, instaurando una nuova connessione

Manno, proprio no. Leggi bene che cosa fa quel decoratore che hai linkato. Quella cosa si limita, prima di fare una query, a
1) controllare che la connessione ci sia
2) se non c'è, connettersi.
Il problema è che al punto (2) lui suppone che "connettersi" sia una cosa che riesce sempre al primo tentativo. Guarda quel codice, ripeto... Lui dà per scontato che il database sia sempre raggiungibile, quando provi a connetterti. Tutta la sua preoccupazione è che, se per puro caso la connessione era caduta in precedenza, lui prima di fare una query ti ri-connette... ma poi non si pone davvero il problema di che cosa succede se la ri-connessione a questo punto fallisce. (In effetti, quello che succede è che se la (ri)connessione fallisce, tutto si pianta con un'eccezione non gestita... ripeto, leggi bene quel codice che hai linkato, e capisci che cosa fa davvero).
Il nostro OP, invece vuole proprio fare in modo che se la connessione fallisce, lui non si pianta ma continua imperterrito a bussare alla stessa porta all'infinito finché la porta non si apre. Ripeto, in linea di principio è un'idea molto discutibile, ma l'OP vuole così e "per lui funziona", quindi... no problem.



Ora, adesso andiamo completamente off-topic per il problema dell'OP, ma è tanto per completare il discorso su quel codice che hai linkato. Per comodità, lo ricopio qui:

def connect(func):
    def inner_func(conn, *args, **kwargs):
        try:
            conn.execute('SELECT name FROM sqlite_temp_master WHERE type="table";')
        except (AttributeError, sqlite3.ProgrammingError):
            conn = connect_to_db(DB_name)
        return func(conn, *args, **kwargs)
    return inner_func

A questo punto magari ti stai chiedendo: ma se quel decoratore non serve a niente per il problema dell'OP, allora a che cosa serve?
Intendiamoci, chiaramente potrebbe darsi che a un certo punto la connessione cade. Per esempio, qualcuno ha staccato il cavo di rete. A questo punto il decoratore prova a fare "conn.execute", questo fallisce, e lui si riconnette.
Ora, primo problemino... se la connessione è caduta perché il db è irraggiungibile (qualcuno ha staccato il cavo di rete, diciamo), l'eccezione che pianta è "sqlite3.OperationalError", non "ProgrammingError" (che non c'entra niente in uno scenario del genere). Quindi già quel coso non intrappolerebbe il fallimento, e si schianterebbe come niente (AHHH, e magari perché non TESTARE IL CODICE CHE SI SCRIVE PRIMA DI PUBBLICARLO...!!!) Ma vabbè, lasciamo perdere... diciamo di correggere l'errore e andiamo avanti.
Il problema vero è che se il cavo di rete è staccato, è staccato. Continua a essere staccato anche al momento di provare a riconnettersi, nel blocco "except"... quindi a quel punto (riga 6) la connessione pianta di nuovo un OperationalError che però questa volta non è chiuso in un "try"... quindi si pianta e basta, come è ovvio.

Buffo, vero? Basta mettersi lì e PENSARE un minuto. Se la connessione "non funziona" alla riga 4 di quel codice, perché uno deve aspettarsi che invece poi "funziona" riprovandoci alla riga 6, qualche millisecondo più tardi? Va bene essere fortunati, ma qui si esagera... In confronto alla palese insensatezza di questo codice, tutto sommato la richiesta dell'OP sembra più ragionevole...

Ma allora... perché l'autore di quel post ha sentito il bisogno di scrivere quel codice? Ehm... semplicemente perché non ha capito come funziona sqlite. A parziale discolpa, quel post riguarda un altro argomento (il pattern mcv) e magari l'autore semplicemente ha usato sqlite per fare prima, ma non ha dimestichezza con quel database. Intendiamoci: prima di scrivere una cosa così insensata, magari un sospetto poteva farselo venire... Ma tant'è.
Che cosa quindi l'autore (credo) non ha capito di sqlite? Lui, per qualche ragione, è convinto che sqlite faccia SPONTANEAMENTE cadere la connessione dopo un certo periodo di inattività... addirittura 5 secondi di default, niente meno! Ora, qui c'è veramente da rotolarsi dalle risate... ma voglio dire, possibile che l'autore non abbia provato a tenere aperta una connessione per più di 5 secondi, e rendersi conto che quella resta tranquillamente in piedi? Vabbè va... diciamo che sono cose che scappano.

Il motivo di questa confusione è che "sqlite3.connect" https://docs.python.org/3.8/library/sqlite3.html#sqlite3.connect ha in effetti un parametro "timeout", che per default è impostato a 5 secondi... ma non significa affatto quello che l'autore immagina (la documentazione peraltro è piuttosto chiara... boh?). Quel timeout significa solo che
1) quando fai una query che modifica una tabella, ma
2) trovi che la tabella è già bloccata da un'altra transazione in corso...
3) allora la tua query aspetta per cinque secondi che la tabella si sblocchi, dopo di che solleva un'eccezione.
Quindi,
1) non significa affatto che dopo 5 secondi di inattività la connessione cade (che assurdità),
2) e comunque anche in caso query che resta bloccata per più di 5 secondi, la connessione NON cade proprio! semplicemente la tua query fallisce con un'eccezione (sempre OperationalError, per la cronaca), ma la connessione resta tranquillamente in piedi, ci mancherebbe... come faccio a sapere questo? perché l'ho testato. Eh già. Proprio così.

In definitiva, quel decoratore potrebbe servire solo in un caso: quando tu hai CHIUSO la connessione in modo regolare, ma NON SAI di averlo fatto (non ridere... in certi scenari potrebbe succedere... anche se sospetterei che si tratti di cattivo design)... allora in effetti la connessione non esiste, ma quando subito dopo provi a riconnetterti trovi il database bello pronto che ti aspetta...
Ma quel decoratore non ti protegge dai casi in cui la connessione cade per cause imprevedibili. Non ti protegge da... boh, da niente o quasi, in effetti.

Ecco, fine dell'analisi di quel decoratore.

6
Base / Re:gestire Errore con while loop senza uscire
« il: Febbraio 19, 2020, 19:09 »
@nunzio
Sì è una tecnica possibile... ma tieni conto che quel decoratore NON fa quello che chiede l'OP... anzi dal punto di vista dell'OP sarebbe fragile... Le librerie di retrying che ho suggerito fanno quello che chiede l'OP (usando effettivamente un decoratore come api).
(questo non vuol dire che sia ciò che chiede l'OP, sia ciò che fa il decoratore del tuo articolo siano delle buone idee, eh... ;-)

@OP
Abbi pazienza ma mi sa che non hai capito il punto. Il punto non era "prima non funzionava, adesso ho capito come dargli due martellate e così funziona". Il punto era "fare bene le cose, o farle male".
(del resto, detto tra parentesi, a me dà un po' i brividi il concetto di "connessione che casca... boh... ci riprovo..." voglio dire, spero che almeno tu lavori con le transazioni in modo corretto... poi sì, certo, come no... "ma nel mio caso funziona comunque".... vabbè...)
Ora, questo non vuol dire che tu non possa costruire dei sistemi che gestiscono il fallimento di una connessione a un db... ci mancherebbe... ma almeno componentizza... non puo fare in modo che lo stesso componente che si connette fa anche le query e si preoccupa di riprovare all'infinito se la connessione fallisce... quello che hai scritto era una filastrocca di codice indigeribile...

7
Base / Re:gestire Errore con while loop senza uscire
« il: Febbraio 19, 2020, 10:31 »
Mah?
Quando devi aprire una porta, *sicuramente* c'è la possibilità che la trovi chiusa a chiave. Ma se accade questo, che cosa fai, mica ti metti a continuare a girare la maniglia all'infinito sperando che cambi qualcosa, no?

Ora, diciamo che il pattern "se una cosa non riesce, riprovaci" non è, in generale, sbagliato a priori. Di solito non si prova all'infinito, in genere si tende a riprovare un certo numero di volte (3...) magari a una certa distanza di tempo, e poi ci si rassegna al fallimento.
Tempo fa avevo visto due piccole utility che ti aiutavano con questo pattern: https://github.com/rholder/retrying e https://github.com/invl/retry. Ormai vedo che non sono più mantenute da anni, ma si tratta di codice talmente semplice e talmente breve che puoi provare comunque a dargli un'occhiata. Adesso vedo invece che c'è questo https://github.com/jd/tenacity più aggiornato. Forse vale la pena di partire da qui.

Nel tuo caso specifico, comunque, il codice che hai scritto non ha senso, e mi chiedo da dove ti possa essere venuta l'idea. Voglio dire, di tutorial in giro per lavorare con i database non è che ce ne siano, e i pattern di lavoro sono abbastanza consolidati. Prima si apre una connessione (ok, qui un ORM ti darebbe probabilmente un pool di connessioni... ma non importa), la si mantiene aperta, poi si fanno query su quella connessione.
Tutto questo può fallire in vari modi, si capisce. Ma sono stadi separati e non vanno certo "annidati".
E del resto, come pensavi di fare? Se fai una query (ciclo while annidato) e fallisce perché il database è diventato irraggiungibile, dovresti riprovare a connetterti (altro ciclo while annidato) e poi rifare una query (altro ciclo while annidato)... e vai avanti all'infinito a collezionare bamboline russe?

Un'altra considerazione filosofica è questa: va bene l'ideale di "mantenere un programma sempre in vita", ma che senso ha mantenere comunque in vita un programma che non funziona? Lo fai così per puntiglio? Se la connessione al database fallisce perché il database è irraggiungibile, tu certamente puoi riprovare all'infinito a connetterti, ma di fatto il tuo programma non può farci niente... non è che può inventarsi una risorsa di rete (o una rete) che non c'è. Puoi riprovare un paio di volte a trenta secondi di distanza (vedi sopra), ma poi il tuo programma deve mandare un messaggio all'utente che dice "guarda, il database non c'è, non posso farci niente, telefona all'amministratore di rete e veditela con lui". Ed esce di scena. Punto. L'utente verifica che la rete sia a posto, e riavvia il programma (o si riconnette al sito, se è una web app... quello che è).
Tra l'altro, se in una situazione del genere il tuo programma continuasse a riprovare all'infinito, come minimo (minimo) staresti facendo un disservizio all'utente: tu gli stai facendo credere che il tuo programma davvero potrebbe risolvere il problema, mentre tutto quello che stai facendo è continuare a girare la maniglia di una porta chiusa a chiave. Se non puoi farci niente, è più onesto dirlo con chiarezza.

Ribadisco il principio.
Un software non deve "fare tutto" e "pensare a tutto". Un software opera in certe condizioni, appoggiandosi a certe risorse. Ma non è responsabile delle condizioni e delle risorse. Se le condizioni e le risorse falliscono, il programma smette di funzionare, e non è compito suo risolvere problemi che stanno al di fuori di lui. Questo è un principio di design fondamentale. Ovviamente tu devi cercare di gestire il fallimento in maniera elegante (avvertire l'utente del problema, non lasciare stati inconsistenti in giro per quanto possibile, etc.) ma il punto è che comunque devi fallire e uscire. Stop.

Ora, tornando al tuo caso. Per prima cosa, ti connetti al database. Questa operazione può fallire per diverse ragioni:
- per ragioni "interne" al tuo programma (l'utente ha messo la password sbagliata, va a sapere): in questo caso correggi l'errore (sì, in teoria qui potresti davvero continuare all'infinito a chiedere la password all'utente... se l'utente non la sa, chiuderà lui il programma...)
- per ragioni "esterne" al tuo programma (qualcuno ha staccato il cavo di rete). In questo caso il tuo programma comunica il problema ed esce. Al massimo puoi riprovare due o tre volte, ma francamente non lo vedo necessario.
Una volta che hai in mano una connessione, la tieni aperta e la usi per farci delle query. Ora, ciascuna query può fallire per diverse ragioni:
- per ragioni "interne" (i dati sono inconsistenti, va a sapere): qui devi preoccuparti in vari modi di intercettare e gestire i potenziali errori
- per ragioni "esterne" (nel frattempo qualcuno ha staccato il cavo di rete): qui informi l'utente del problema e chiudi.

In tutto questo, naturalmente, c'è sempre da dire che per usare un database conviene affidarsi a un ORM... tipo sqlalchemy o cose del genere. Almeno in questo modo i pattern giusti te li costruisce l'ORM... Comunque, se vuoi fare tutto a mano, puoi farlo. L'importante è che tu faccia chiarezza su quello che il tuo programma può e deve fare, e quello che non può e non deve fare.

8
PyQT / Re:come utilizzare sympy in pyqt5
« il: Febbraio 18, 2020, 15:46 »
> Che domanda "strana"

Si chiama "dare martellate alla cieca". E' partito da questo https://forumpython.it/pyqt/come-ottenere-un-valore-da-una-stringa-a-cui-e'-stato-assegnato-un-valore , al che ho più o meno intuito che stava cercando di fare algebra simbolica con una gui in Qy, gli ho vagamente consigliato di appoggiarsi a SymPy, ed ecco che puntuale come un orologio arriva lo stadio successivo... "come integrare etc etc?".
(e naturalmente poi *non lo so* se sta davvero cercando di fare una cosa generale come "algebra simbolica", oppure ha un problema molto più circoscritto che sarebbe risolvibile con un po' di pianificazione ad-hoc... va a sapere)

Ora, la risposta alla domanda sarebbe: certo, si può fare. Banalmente, prelevi dalla gui l'espressione che ti serve (espressa nei termini di simboli che hai già definito, oppure magari anche di simboli che prelevi anche loro dalla gui...), la passi a SymPy e la fai valutare/risolvere a SymPy. La gui è la parte banale. Tutto il resto, è più o meno difficile come seguire il tutorial di SymPy.

Ma la *vera* risposta è: non si impara Python a botte di post sui forum. Si prende un buon libro di base e lo si segue passo-passo, pagina per pagina, prendendosi un anno tranquillo di tempo. Poi si passa alle gui, e ai progetti di algebra simbolica, alle librerie complicate, etc. etc.

9
Programmazione in rete - web / Re:Lavorare su server
« il: Febbraio 17, 2020, 18:48 »
> Per ciò che riguarda "broken pipe" dubito ci sia qualcuno che stacca il cavo di rete per farmi un dispetto.

(eh...) Era un modo di dire. Se interrompi la connessione in modo scorretto (come per dire..., hai capito..., come se staccassi il cavo di rete... eh già) per esempio killando il processo senza troppi complimenti, è ben possibile che ti troverai in mano una broken pipe... e magari puoi anche ignorare la cosa, eh...

> non mi sia possibile utilizzare una soluzione gestita

Mah, saprai tu, ma in genere finisce per essere quello che fanno un po' tutti... Proprio perché così puoi concentrarti sul tuo problema specifico e non sui dettagli noiosi di come funziona un server.

> come funziona una connessione ssh, una pipe e tutto il resto

Mah, sì... e intendiamoci, non è una cosa necessariamente sbagliata imparare un po' di "meccanica". E magari è anche la cosa più facile nella tua situazione.
Oppure potresti vedere se esiste un modo di appoggiarti a qualche application framework (e magari scritto in Python... tanto per avvicinarci un pochino all'in-topic)... E' per certi aspetti una situazione analoga a questa https://forumpython.it/programmazione-in-rete-web/un-consiglio-su-cosa-andare-a-guardare/msg89034/#msg89034

10
Programmazione in rete - web / Re:Lavorare su server
« il: Febbraio 17, 2020, 14:17 »
Guarda, così come per il quasi identico messaggio che hai postato sull'altro forum, non è che ti si possa rispondere un granché, dal nulla che scrivi. Un "server" non è un'entità magica di qualche tipo: è un computer su cui girano dei software. Ora, dipende da che architettura usi per lavorare, lato server e lato client (il tuo). Un "memory error" può essere dovuto al fatto che il server limita la quantità di memoria disponibile a una shell remota, o va a sapere gli altri mille motivi. Un "killed" è il tipo di risultato che ottieni quando sei un po' scarso a Call of Duty. Una "broken pipe" è quando per fare prima termini la connessione staccando il cavo di rete. Che posso dirti...? Tutto questo non ha niente a che vedere con Python (almeno, a quanto capisco dal nulla che ci stai dicendo... poi magari invece hai sbattuto in qualche baco o qualche errore di configurazione di Urbansim... ma non possiamo saperlo).
In generale, il mio consiglio sarebbe, se non sei sicuro di come in effetti "lavorare su server", prova invece a prenderti una soluzione gestita di quelle che già esistono... AWS lambda, per dire la cosa più scontata... Questo almeno ti toglie la difficoltà di doverti imparare i dettagli di come funziona davvero una connessione ssh, una pipe, la gestione della memoria... etc. etc.

11
Guarda, il minimo sindacale è usare "eval":

>>> a = 10 # questo, poniamo, è una casella di input
>>> b = 20 # altra casella
>>> expression = "a * 10 + b" # altra casella di input
>>> eval(expression) # questo avviene al clic su un pulsante
120

Ora, se non ti viene proprio nessun brivido a fare una cosa del genere, allora vai pure avanti senza problemi. Il computer è tuo...
Viceversa, dovresti scriverti un parser, o formulare comunque il tuo problema in un modo più stringente. Tutto questo non c'entra assolutamente niente con le gui e con le Qt, beninteso.
Appoggiarti a un framework già esistente in questi casi può essere una buona idea. Se non lo hai mai sentito, puoi googlare senza problemi... occorre solo la concentrazine necessaria a scriverlo correttamente: SymPy e non "Simpsy".

Uhm, da molto tempo ormai questo forum ha problemi con gli allegati pesanti... e in generale è un bene che sia così. L'ideale sarebbe impedire completamente gli allegati. Un forum non è fatto per scambiare centinaia di righe di codice... chi chiede aiuto e consiglio su un forum dovrebbe avere la cortesia operativa di formulare il suo problema in modo sintetico, scrivendo appositamente una versione ridotta all'osso del suo codice, che evidenzia il problema ed elimina tutte le parti che non c'entrano col problema. Scaricare un dump di centinaia di righe ingarbugliate è molto facile per chi pone la domanda, ma rende difficile il lavoro di chi vorrebbe rispondere.
Impedire o limitare gli allegati aiuta un pochino a orientare le persone verso alcune regole di netiquette. Poi, nei casi dove proprio c'è bisogno di sottoporre porzioni estese di codice, si può sempre appoggiarle su pastebin o cose del genere, e mettere solo il link nel post.


12
Database / Re:Anaconda e netbeans
« il: Febbraio 17, 2020, 12:27 »
Guarda, netbeans è un ide serio, con una tradizione robusta. E' anche un ide pesantemente orientato a java, e onestamente non ho proprio idea di quanto seguito abbia ancora tra gli sviluppatori python nel 2020. Ora io non so chi possa consigliare Netbeans come ide per python, ma... boh ormai ho smesso di farmi queste domande. Qui in Italia siamo veramente la periferia dell'impero, siamo rimasti a Pensare da informatico, ci sono dozzine di esempi in rete che usano "os.system", e dozzine di professori universitari che insegnano python come se fosse java, e java come se vosse visualbasic. Boh.
Detto questo, non è che netbeans non si possa usare, eh. Anzi. Sicuramente scavando tra le opzioni trovi il modo di indicargli che vuoi lavorare con un particolare ambiente python (ovvero quello di anaconda), tra quelli installati sulla tua macchina. Non metto in dubbio che un ide serio come Netbeans si possa configurare alla perfezione, volendo. Devi solo scoprire come si fa...

Edit: che cosa poi questo post abbia a che vedere con la sezione "database", è un mistero oltre le mie capacità.

13
Abbi pazienza ma questo post è scritto in una lingua che io non riesco a comprendere. In ogni caso, intuisco che vuoi fare algebra simbolica e se è così ti consiglierei di appoggiarti a Sympy, o cose del genere.

14
Mah, non si improvvisa una web app, ma non si improvvisa nemmeno fare networking a botte di socket... Anzi caso mai un web framework ti astrae la complessità dei protocolli sottostanti.
Comunque se hai XP a 32 bit, allora hai dei problemi molto più gravi di tutto il resto.

15
A parte che non capisco perché anche i client non possano essere scritti in python... non è non si possa usare python su computer vecchi, eh.
Comunque non saprei... certo uno potrebbe, in teoria, mettersi a lavorare coi socket (web, immagino)... non è che manchi la documentazione, a partire da https://docs.python.org/3/howto/sockets.html#socket-howto ma questo mi sembra molto ben fatto https://realpython.com/python-sockets/
Il problema è che... non so, è proprio così necessario mettersi a inventare la ruota daccapo? Cioè, poi magari invece sì, nel senso che se il tuo problema si risolve in uno script di poche decine di righe, allora effettivamente usare banalmente socket dalla libreria standard basta e avanza.
In linea di principio, per questi problemi si usa un framework però. Ora una volta Twisted era la strada maestra, ma oggi purtroppo lo stato è quello che è... Però uno può sempre buttarsi su Tornado, per dire...
Ma poi, più in specifico... non è che questa cosa potrebbe essere banalmente una web app? Perché a questo punto forse basta Django, o magari Flask... e se il client potesse girare in un browser, ti risparmieresti anche la gui desktop in java... va a sapere.

Pagine: [1] 2 3 ... 225