How to create an object by requesting data from the user and running from a function?

Asked

Viewed 41 times

-2

I created a simple class, I can create an object, but I’m developing a CRUD that needs to create the object from a function. Look at my example:

class Funcionario:
    def __init__(self, nome, cargo, salario):
        self.nome = nome
        self.cargo = cargo
        self.salario = salario


def registrar():
    func = Funcionario(
        nome = input('Nome: '),
        cargo = input('Cargo: '),
        salario=(input('Salário: '))
    )

def modificar():
    func ?

The problem is that the creation of the object stays within the function, that is, it is not global.

If I try to create a method change in the class and I will run from a function edit the position, for example, how do I instantiate the object, being that it is in the other function? And if I leave out, he keeps calling all the time the creation of the object, which I don’t want.


Complete code:

class Funcionario:
    def __init__(self, nome, cargo, salario):
        self.nome = nome
        self.cargo = cargo
        self.salario = salario
    
    def altera_cargo(self):
        novo_cargo = input('Novo cargo: ')
        self.cargo = novo_cargo
        print('Cargo atualizado para {}'.format(self.cargo))
    
    def altera_salario(self):
        novo_salario = float(input('Novo salário: '))
        self.salario = novo_salario
        print('Salário atualizado para R$ {}'.format(self.salario))


def registra():
    return Funcionario(
        nome = input('Nome: '),
        cargo = input('Cargo: '),
        salario = float(input('Salário: '))
    )


def menu():
    opcao = int(input('1. Novo\n2. Editar cargo\n3. Editar salário\n--> '))

    if opcao == 1:
        registra()
        print('\n')
        menu()
    if opcao == 2:
        altera_cargo() # como acessar o objeto ?
        print('\n')
        menu()
    if opcao == 3:
        altera_salario() # como acessar o objeto ?
        print('\n')
        menu()
    else:
        exit()

if __name__ == "__main__":
    menu()

1 answer

0


Just make the function return the employee who was created. Then you pass this employee to the function you modify, and inside you change the data you need. Ex:

def registrar(): # retorna um novo funcionario
    return Funcionario(
        nome = input('Nome: '),
        cargo = input('Cargo: '),
        salario = float(input('Salário: '))
    )

def modificar(func): # modifica os dados de um funcionário
    func.salario = float(input('Novo salário:'))
    func.cargo = input('Novo cargo:')
    # etc...

# registra um funcionário e modifica
funcionario = registrar()
modificar(funcionario)

# registra outro funcionário e modifica
outro_funcionario = registrar()
modificar(outro_funcionario)

etc...

The return causes the value to be returned to whoever called the function. Thus, each call to registrar returns a new instance of Funcionario, that you can handle separately.

And the function modificar receives an employee as a parameter, and inside it modifies the data of this.

Note: I used float to convert the salary to a number, because it seems to me that it does not make sense the salary to be a string (just remembering that will give error if it is not typed a number).


Now, if the idea is to call the employee’s own methods, then first you need to create it.

And if you want to keep repeating the menu several times, don’t call the function within itself. Instead, do a loop infinite and interrupt it using break:

def menu():
    func = None
    while True:
        opcao = int(input('1. Novo\n2. Editar cargo\n3. Editar salário\n--> '))
        if opcao == 1:
            func = registra()
        elif opcao == 2:
            if func is None:
                print('funcionário ainda não foi criado')
            else:
                func.altera_cargo()
        elif opcao == 3:
            if func is None:
                print('funcionário ainda não foi criado')
            else:
                func.altera_salario()
        else:
            break # sai do loop
        print('\n')

I mean, I have an employee func which at first has no value (None). When registering, the function registra() returns this employee, and once having him, I can call the methods of it (altera_cargo and altera_salario).

Look at the while True, he keeps repeating everything until he finds one break (the difference is that exit leaves the program, now break interrupts only the while, so if there was any code after him, this one would run).

That’s better than what you did, 'cause you keep calling the function menu within itself (which is called recursion) can cause a stack overflow. Prefer to use a loop, who doesn’t have that problem.

  • I answered your comment with a question, sorry. Can you take a look at the question panel?

  • @Tguitarful In fact you used the answer field, which is intended only for solutions. The right thing is you edit the question and put the code there (I already did, but next time, edit the question itself) - I also updated my answer

  • Oops, the way you showed it worked really, thank you! Sorry to be insistent, is that the code is getting more and more complex. The main idea is to separate it. So for example, as the function was tied to the menu function, it was inaccessible outside. The intention now is to create a function for each task, create, modify, delete and query. The object that is created needs to be accessible to all these functions, since the menu will now be in a separate file and will call these functions when necessary. As well as write to the database as well.

  • @Tguitarful Please understand that the format of [pt.so] is for questions/answers. You ask a specific question and people answer only that, nothing else. It’s not like in a forum, where the discussion can lengthen and the problem can change. So if you have another question (even if it is related to this one), the best is ask another question. But in general, it would be enough to do the job menu return the employee. There who call the menu takes the turn (func1 = menu(), afterward func2 = menu(), etc.)...

  • ...and you use these employees any way you want. Of course, there are many ways to do it, so maybe another question is better, because then the answers can be more focused. But anyway, if the answer solved your problem (which is in the question, not the other one you just mentioned), you can accept it, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem. As for the other problem, I suggest you ask another question...

  • ...which is better, not only to keep the site more organized - a question by specific problem - but also because new questions become visible on the main page, then everyone can see and you have more chances to have an answer. Putting in the comments, less people will see.

  • Yes, I’m still getting used to the format of the site. Anyway vlw by the help. In the original post, your answer solved the problem! Thank you for the force!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.