I believe the problem has been solved in the other answers, but I will leave here a suggestion of how I would solve the problem, if you are interested in studying an alternative.
First, you have 4 well-defined tasks in your project:
Display the menu;
Option 1, to register a person;
Option 2, to list the registered people;
Option 3, to search for a person's data;
Why, then, do not create a function for each?
Displaying the menu ...
def exibir_menu():
print('''Escolha uma opção:
1. Cadastrar uma pessoa
2. Listar pessoas cadastradas
3. Procurar dados de uma pessoa
''')
Registering a person ...
def cadastrar(pessoas):
identificador = input('Id? ')
nome = input('Nome? ')
idade = int(input('Idade? '))
pessoas.append((identificador, nome, idade))
Considerations would be:
- Do not use an object called
id
because it is the name of a native Python function;
- The value of
idade
is converted to integer because it is a number - this will make it easier to sort the list by age;
- A tuple was created with the data - note the presence of two parentheses in
append
;
Using the tuple follows the same logic that you used with the list, to save the grouped values, but with tuple the code becomes more semantic.
When to use lists and when to use tuples?
Listing people ...
def listar(pessoas):
for pessoa in pessoas:
identificador, nome, idade = pessoa
print(f'Nome: {nome}, idade: {idade}, id: {identificador}')
Here, I use tuple deconstruction to pass the tuple pessoa
, which has the three information of the person, for three different variables; so the code will be much more readable because it is easier to understand that nome
is the name of the person to pessoa[1]
. And to display the information, I used Python 3.6's f-strings , where, for example, {nome}
will be replaced with nome
.
Searching for a person ...
def buscar(pessoas):
identificador_desejado = input('Id? ')
for pessoa in pessoas:
identificador, nome, idade = pessoa
if identificador == identificador_desejado:
print(f'Nome: {nome}, idade: {idade}, id: {identificador}')
break
else:
print(f'Pessoa com id {identificador_desejado} não encontrada')
It basically traverses the list of people in search of the desired id and, when it finds it, displays the person's information, otherwise the message that the person is not found is displayed.
Putting it all together
So, the code would look something like:
def main():
pessoas = []
while True:
exibir_menu()
opcao = int(input('Opção? '))
if opcao == 1:
cadastrar(pessoas)
elif opcao == 2:
listar(pessoas)
elif opcao == 3:
buscar(pessoas)
else:
print('Opção inválida')
See working at Repl.it
What already greatly improves the readability of the code and facilitates the maintenance of the project. Even so, it is important to note that much could be improved; for example, reading the data is being performed inside the function, along with the logic of registering - that is, they are two responsibilities for the same function, this is not always good to do, since it makes it impossible for you to use the function in other places ( and if I want to register a person who already knows the data? I would have to create another function, duplicating the registration logic, which hurts the DRY principles.)
The same thing happens with other functions, for example. What if I want to send the entire list by email instead of displaying it on the screen? You would need a function other than listar
that would have a fairly similar logic.
Another trivial change to be made that would greatly improve the readability of the code would be to use namedtuple
, rather than just tuples, thereby dispensing with the need to deconstruct the tuple for variables.
That said, I leave these improvements open for you, if you, or anyone who is reading, search for your own development of such improvements in the code and, if you do, post here as it will be useful for many users.