Domanda ricerca attributi in una classe

Maxwell2609

Utente Silver
29 Ottobre 2020
137
24
33
75
Salve, ho un problema con il seguente script:
Python:
class Personale:
    def __init__(self,nome, meccanica, chimica, riparazioni):
        self.nome=nome
        self.meccanica=meccanica
        self.chimica=chimica
        self.riparazioni=riparazioni

pers1 = Personale("Nome1",1,1,1)
pers2 = Personale("Nome2",1,1,0)
pers3 = Personale("Nome3",1,0,1)

competenza = input("Competenza richiesta:")

Devo fare in modo che lo script, dato un valore in input corrispondente ad una competenza, stampi a schermo i nomi di tutti gli impiegati che la possiedono.
Esempio: se voglio cercare tutti quelli con competenze chimiche, inserendo "chimiche", lo script stampi a schermo Nome1 e Nome3. Come posso fare in modo che venga eseguita una ricerca automatica nella classe, dunque prendere in considerazione solo alcuni impiegati, e stamparli a schermo? Preferirei un processo generale, come un ciclo che controlli ogni singolo impiegato visto che nel caso finale si tratteranno di diverse decine di individui. Grazie.
 
Non puoi fare una "ricerca nella classe", devi farla sulle istanze (pers1, 2 e 3). Percio' aggiungi in un array i vari oggetti e con un ciclo verifichi se la competenza richiesta e' presente in quel dato oggetto.

Pseudocodice (non conosco python nello specifico):
Codice:
Persone = [pers1, pers2, pers3];
competenza = "chimica";
foreach (persona in Persone) {
    match = false;
    if (competenza == "chimica" && persona.chimica == 1)
        match = true;
    // elseif (...)
  
    if (match)
        print(persona.nome + " ha la competenza " + competenza);
}
 
Ultima modifica:
Python:
class Personale:
    def __init__(self,nome, meccanica, chimica, riparazioni):
        self.nome=nome
        self.meccanica=meccanica
        self.chimica=chimica
        self.riparazioni=riparazioni

    def has_competence(self, comp):
        dc = {
            'meccanica' : lambda : self.meccanica,
            'chimica' : lambda : self.chimica,
            'riparazioni' : lambda : self.riparazioni,
        }
    
        return dc.get(comp, False)


#usage example:
person = Personale('Giovanni', 1,1,1)

if person.hash_competence('meccanica'):
    print(person.nome + " has 'meccanica' competence")

#expected output:
#Giovanni has 'meccanica' competence





Non puoi fare una "ricerca nella classe", devi farla sulle istanze (pers1, 2 e 3). Percio' aggiungi in un array i vari oggetti e con un ciclo verifichi se la competenza richiesta e' presente in quel dato oggetto.

Pseudocodice (non conosco python nello specifico):
Codice:
Persone = [pers1, pers2, pers3];
competenza = "chimica";
foreach (persona in Persone) {
    match = false;
    if (competenza == "chimica" && persona.chimica == 1)
        match = true;
    // elseif (...)

    if (match)
        print(persona.nome + " ha la competenza " + competenza);
}
Il tuo codice non è errato, ma il fatto che non possa farlo nella classe, ni.
Dipende cosa intendevi.





Onestamente imposterei anche il codice leggermente diverso, per renderlo un pò più modulare e generico, non specifico.
Un esempio potrebbe essere:
Python:
import sys

class Personale():
   
    def __init__(self, nome):
        self.competenze = set()
        self.nome = nome
       
    def aggiungi_competenza(self, competenza):
        self.competenze.add(competenza)
   
    def ha_competenza(self, competenza):
        return competenza in self.competenze
   

#leggendo i dati da un file (immagino tu avrai un input simile dei dati)
personale = [] #lista vuota che conterrà gli oggetti Personale instanziati

try:
    file_data = open('database.txt', 'r')
    lines = [line.strip() for line in file_data.readlines()]
    for line in lines:
        data = line.split('\t') #split data by tab
       
        #ogni riga deve avere almeno il nome
        if len(data) < 1:
            continue
       
        nome = data[0]
        competenze = data[1:]
       
        dip = Personale(nome)
        for competenza in competenze:
            dip.aggiungi_competenza(competenza)
       
        personale.append(dip)
   
except:
    print("Impossibile procedere senza il file database.txt")
    sys.exit(1)
   
#esempio di esame dei dati dall'utente

while True:
    competenza = input('cerca personale in base a una competenza (scrivi esci per uscire) : ')
   
    if competenza == 'esci':
        break
   
    for dip in personale:
        if dip.ha_competenza(competenza):
            print("%s ha la competenza ricercata (%s) "%(dip.nome, competenza))



un esempio di input file protebbe essere qualcosa del genere (occhio ai tab):

Codice:
Giovanni    Meccanica    Chimica
Alessio    Meccanica
Marco    Meccanica    Chimica    Riparazioni
 
Il tuo codice non è errato, ma il fatto che non possa farlo nella classe, ni.
Dipende cosa intendevi.
L'unica differenza di codice e' che il controllo tu lo fai in un metodo della classe. Intendo che la ricerca va fatta su gli oggetti e non sulla classe: se tu dichiari 1000 oggetti di classe Personale e poi non ne tieni traccia (ad esempio in un array) non puoi fare una ricerca avendo solo la classe Personale, cosa che sembrava volesse fare dalla domanda.