Topic: Nuove variabili tramite istruzione  (Letto 123 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Alien92

  • python unicellularis
  • *
  • Post: 10
  • Punti reputazione: 0
    • Mostra profilo
Nuove variabili tramite istruzione
« il: Agosto 19, 2021, 18:14 »
Salve a tutti, posto il problema in questa sezione perché non so in quale altra sezione potrebbe andare bene, se sapete indicarmela in caso sposto.
Vorrei scrivere un piccolo sistema che immagazzina dei dati personali di varie persone, e questo implica un grande utilizzo delle variabili/degli oggetti, e vorrei evitare di scrivere tutte le variabili a mano, sia perché è abbastanza noioso sia perché magari aggiungendo sempre più persone le variabili disponibili finiscono, e questo causa il ritorno alla prima motivazione.
Esiste un modo per creare nuove variabili tramite un'istruzione di python, magari da implementare in una funzione?
Per esempio, mettiamo caso che io abbia creato un'interfaccia grafica con tkinter, e abbia creato un bottone. C'è modo che quel bottone se premuto crei una nuova variabile senza averla prima dovuta scrivere a mano?

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.183
  • Punti reputazione: 9
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #1 il: Agosto 20, 2021, 10:13 »
uhm... ho il dubbio che tu non abbia capito che cosa è una variabile, e a che cosa serve... fammi capire, tu come faresti "a mano"? puoi fare un esempio, diciamo con i dati personali di due persone?
E anche, per capire il contesto, su quale libro stai studiando Python?

Offline Alien92

  • python unicellularis
  • *
  • Post: 10
  • Punti reputazione: 0
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #2 il: Agosto 20, 2021, 14:53 »
Ok, cerco di chiarire.
Creo una classe per generare un modello generico di persona con nome, congnome, età e residenza

class person:
    def __init__(self, name, surname, age, residence):
        self.name = name
        self.surname = surname
        self.age = age
        self.residence = residence

    def profile(self):
        prof = f"""
        Nome: {self.name}
        Cognome: {self.surname}
        Età: {self.age}
        Residenza: {self.residence}
        """
        return prof

pers1 = person('Mario', 'Rossi', '34', 'Via Roma 2')


Se ho studiato bene la programmazione a oggetti, pers1 è una variabile a cui è stato assegnato un oggetto, ma molto probabilmente potrei sbagliarmi.
Il fulcro dell'esempio è che in un progetto simile in cui verrebbero immesse tante persone, sarebbe abbastanza noioso e richiederebbe molto tempo scrivere a mano (cioè battendo i tasti sulla tastiera ogni volta) pers1, pers2, pers3 ecc...
Quindi mi chiedevo se esiste un'istruzione o una serie di istruzioni per far si che questa cosa si automatizzi ogni volta che ce ne bisogno. Magari, tornando all'esempio del post di prima, con un button su tkinter.

Quanto a dove sto studiando... Non è una fonte unica. Ho provato, all'inizio, di studiare da un libro, ma non mi ci sono trovato bene, quindi ho iniziato a cercare tutorial su youtube, corsi e esempi di codice online per cercare di capire cosa facevano le singole parti e sono giunto fin qua. Adesso mi ritengo abbastanza soddisfatto, quindi volevo provare a studiare un nuovo linguaggio, pur continuando a studiare python.

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.183
  • Punti reputazione: 9
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #3 il: Agosto 20, 2021, 18:46 »
Uhm, ok. A occhio, direi che sei arrivato oltre lo stadio "non ho chiaro che cosa è una variabile". Il che... complica la spiegazione, sigh.

Allora, per prima cosa, non esiste niente nella *sintassi* di Python che risolve il tuo problema. Di base, un oggetto è un oggetto. E se vuoi raggiungere un oggetto (usarlo), allora devi avere un nome (una variabile) che punta a quell'oggetto. E una variabile non può certo puntare a più oggetti contemporaneamente. Fine della storia.
Quindi sì, di base quello che devi fare è creare tanti oggetti (tante istanze della classe Person - p maiuscola, tra parentesi) se hai bisogno di lavorare contemporaneamente con tanti oggetti del tipo Person.

Ovviamente ci sono dei pattern tipici... per esempio, spesso vuoi ficcare i tuoi oggetti in un contenitore, per esempio una lista:

>>> mario = Person('Mario', 'Rossi', '42') # abbrevio un po'
>>> maria = Person('Maria', 'Bianchi', '23')
>>> gianni = Person('Gianni', 'Verdi', '64')
>>> persons = [mario, maria, gianni]

Il vantaggio è che ora puoi, per dire, ciclare con un for e compiere la stessa operazione su tutti gli oggetti:

>>> for person in persons:
        print(person.age)
        person.profile() # eccetera eccetera

Spesso è anche comodo se il contenitore non è una lista ma un dizionario, tipo:

>>> persons = {'Mario': mario, 'Maria': maria, 'Gianni': gianni}

perché questo ti consente di indirizzare le operazioni sugli oggetti in modo in qualche modo più leggibile, tipo
>>> persons['Maria'].profile()


Ma detto questo, di base non c'è molto di più... se hai bisogno di oggetti, allora hai bisogno di variabili che puntano agli oggetti.

Nota che, se invece NON hai bisogno di oggetti, allora le cose cambiano... per esempio, le tue "persone" potrebbero anche essere semplicemente delle liste di valori... allora tutto il tuo elenco di persone potrebbe stare in una lista di liste

>>> person_list = [['Mario', 'Rossi', '42'], ['Maria', 'Bianchi', '23'], ['Gianni', 'Verdi', '64']]

o in un dizionario di liste, se vuoi
>>> person_dict = {'Mario': ['Mario', 'Rossi', '42'], 'Maria': ['Maria', 'Bianchi', '23'], 'Gianni': ['Gianni', 'Verdi', '64']}

allora è chiaro che per tutto questo basta una sola variabile... e puoi accedere ai dati tramite indirizzamento, tipo

>>> person_list[1][2] # l'età di Maria
>>> person_dict['Gianni'][1] # il cognome di Gianni


E questo è anche molto comune... ma intendiamoci, in questo modo ti perdi tutte le possibilità degli oggetti, tipo i metodi custom. Per esempio, adesso non puoi fare qualcosa come "maria.age" o "gianni.profile()" perché, semplicemente, "maria" e "gianni" non sono oggetti su cui puoi operare, ma semplici dati "piatti" a cui puoi accedere al massimo attraverso gli strumenti standard di Python (indici, etc.)
La forza delle classi è appunto che possono contenere delle operazioni custom da fare sugli oggetti. Ma se hai le classi, allora devi istanziarle e creare gli oggetti per rappresentare i tuoi dati.

Quindi il tuo problema non è tanto di sintassi (ovvero, c'è un modo in Python di fare questo?), quanto piuttosto di design del codice. E qui mi fermo perché non è che posso andare avanti a scrivere per ore. Magari un altro giorno, eh.
Intanto prova a riflettere a fondo su queste cose, e vedi se riesci a cavarne fuori un possibile approccio diverso, e posta qui quello che hai pensato.

Offline Alien92

  • python unicellularis
  • *
  • Post: 10
  • Punti reputazione: 0
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #4 il: Agosto 20, 2021, 20:21 »
Quasi quasi preferivo non avere chiaro cos'è una variabile.

Comunque la spiegazione, nonostante un po' complicata per me all'inizio, è stata molto esaustiva, e mi ha fatto venire in mente la soluzione ad un altro problema che avevo, cioè: "Come posso cercare una persona in particolare, sapendo solo il nome, tra un gruppo molto ampio di variabili?".
La soluzione era abbastanza semplice in realtà, visto che bastava creare un dizionario o una lista.

Quanto al creare nuove variabili automaticamente, si potrebbe magari creare un programma per generare un certo numero di stringhe identiche tranne per il numero identificativo, come pers1, pers2 eccetera, copiarle e poi incollarle nell'editor rimuovendo a mano eventuali caratteri di troppo.
Tipo questo:

variable = 'pers'
num = 1

while True:
    print(variable + str(num), '= ')
    num = num + 1
    if num > 200:   #se no il mio computer esplode da troppe variabili generate
        print('La prossima volta devi ricominciare da', num)
        break


Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.183
  • Punti reputazione: 9
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #5 il: Agosto 20, 2021, 22:05 »
sì, purtroppo programmare è un po'... difficile, non ci sono molti modi per addolcire la pillola...

comunque no, quello che proponi sarebbe impossibile da gestire, se ci pensi lo vedi da solo.

Invece, prova a pensare ancora... Una volta che hai messo gli oggetti dentro una lista (o un dizionario, come vuoi)... hai davvero ancora bisogno di conservare le variabili corrispondenti a quegli oggetti? E se buttassi via le variabili, potresti ancora accedere agli oggetti dentro la lista o al dizionario? e come?
Prova a rifletterci...
Se azzecchi il ragionamento, allora sei già al 10% della soluzione del tuo vero problema.

Offline Alien92

  • python unicellularis
  • *
  • Post: 10
  • Punti reputazione: 0
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #6 il: Agosto 21, 2021, 13:57 »
Non credo di aver capito bene cosa vuoi dire

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 461
  • Punti reputazione: 0
    • Mostra profilo
Re:Nuove variabili tramite istruzione
« Risposta #7 il: Agosto 21, 2021, 17:33 »
Non credo di aver capito bene cosa vuoi dire

Spero che @RicPol non me ne voglia per questo intervento a "gamba tesa", credo Ti stia invitando a relazionare tra loro gli "strumenti" disponibili nel linguaggio e derivare, da proprietà e metodi disponibili una logica di approccio.
Supposto di partire dalla classe da Te esemplificata in precedenza, guarda un po' questo:
>>> class Person:
def __init__(self, name, surname, age, residence):
self.name = name
self.surname = surname
self.age = age
self.residence = residence
def profile(self):
prof = f'''Nome      : {self.name}
Cognome   : {self.surname}
Età       : {self.age}
Residenza : {self.residence}'''
return prof


>>> p = '''Paperon;De Paperoni;111;Paperopoli - Largo Deposito, 1
Paolino;Paperino;43;Paperopoli - via Della Sfiga, 13
Gastone;Paperone;39;Paperopoli - corso Dea Bendata, 1'''
>>> people = [Person(*x.split(';')) for x in p.splitlines()]
>>> for name in people: print('\n' + name.profile())


Nome      : Paperon
Cognome   : De Paperoni
Età       : 111
Residenza : Paperopoli - Largo Deposito, 1

Nome      : Paolino
Cognome   : Paperino
Età       : 43
Residenza : Paperopoli - via Della Sfiga, 13

Nome      : Gastone
Cognome   : Paperone
Età       : 39
Residenza : Paperopoli - corso Dea Bendata, 1
>>> for name in [x for x in people if 'Pao' in x.name]:
print(name.profile())


Nome      : Paolino
Cognome   : Paperino
Età       : 43
Residenza : Paperopoli - via Della Sfiga, 13
>>>

come puoi vedere, partendo da un elenco di dati per tre "paperi" nulla vieta di definire una lista di paperi Person "senza" utilizzare variabili intermedie, memorizzando direttamente le istanze di oggetti "Person" in una lista e poi accedendo ai vari oggetti con i metodi ordinari delle liste o selezionandoli in base ad una qualche loro proprietà.

Di norma, utilizzando una interfaccia grafica, darai all'utente due distinte modalità di accesso ai dati, una sarà ad un elenco dati, di solito per consultazione/selezione, l'altra ad un singolo dato per operazioni specifiche di memorizzazione/aggiornamento/cancellazione.
>>> papero = people[0]
>>> papero.profile()
'Nome      : Paperon\nCognome   : De Paperoni\nEtà       : 111\nResidenza : Paperopoli - Largo Deposito, 1'
>>> papero.name = 'Paperone'
>>> papero.profile()
'Nome      : Paperone\nCognome   : De Paperoni\nEtà       : 111\nResidenza : Paperopoli - Largo Deposito, 1'
>>>

Se ci pensi su, vedrai che già solo così gli scenari cambiano parecchio l'approccio da tenersi ... ed in genere "le cose" sono parecchio più complicate.

L'idea ventilata di creazione di "stringhe identiche" da modificare poi "a mano" oltre la difficile gestione (cosa è quanto modificato?, come ritorna ad essere "dato"?, a cosa serve?) appare diametralmente opposta ad una accettabile valutazione di una problematica da porsi in uno "sviluppo" di applicazione (quali dati ho?, cosa ci devo fare?, come posso trattarli?, etc.)

Spero di aver interpretato correttamente lo "stimolo" dato da @RicPol, che certo avrà mille dettagli da aggiungerci.
Ciao :)