Specifically speaking of your answer, len already returns an integer, then do int(len(etc...)) is redundant and unnecessary. Do only count = len(pesquisa[nome]) // 2 would be enough (using the entire split operator // so that the result is not a float).
But actually dividing by 2 seems to me a little "gambiarra", to circumvent the fact that you are using a list, which does not seem to be the most appropriate structure for this case. If the idea is to have a note for each soda, I think it’s best to use a dictionary that maps the name of each soda with its respective note. It may seem a silly detail ("ah, but with lists it works"), but choosing the right data structure is halfway towards better code.
Then I’d do it this way:
def relatorio_avaliadores(pesquisa):
print('Relatório de Avaliadores')
for nome in sorted(pesquisa):
print(f'{nome} avaliou o total de {len(pesquisa[nome])} produto(s).')
# as notas ficam em outro dicionário
pesquisa = {
'PEDRO': { 'FANTA': 5, 'PEPSI': 4 }, # cada refrigerante é mapeado para sua nota
'ANA': { 'SPRITE': 5, 'COCACOLA': 4 }
}
relatorio_avaliadores(pesquisa)
Note that to sort the keys, I can simply do sorted(pesquisa). And if I just want to print the quantity and I won’t use this value for anything else, nor would I need the variable cont.
And now I don’t have to divide by two anymore, because according to the documentation, the len of a dictionary returns the number of keys of this, and how each key corresponds to a soda evaluated by the person, when using len(pesquisa[nome]) I’ll have the right value.
Another detail is that the way you did it, the function relatorio_avaliadores only worked for the dictionary pesquisa raised out of it. But now I’ve changed the function to receive the dictionary as a parameter, so it works for any other dictionary that has the same structure. Ex:
from operator import itemgetter
def relatorio_avaliadores(pesquisa):
print('Relatório de Avaliadores')
# apenas para mostrar outra forma de iterar pelo dicionário
for nome, notas in sorted(pesquisa.items(), key=itemgetter(0)):
print(f'{nome} avaliou o total de {len(notas)} produto(s).')
# dados de uma pesquisa
pesquisa1 = {
'PEDRO': { 'FANTA': 5, 'PEPSI': 4 },
'ANA': { 'SPRITE': 5, 'COCACOLA': 4 }
}
relatorio_avaliadores(pesquisa1)
# dados de outra pesquisa
pesquisa2 = {
'Fulano': { 'FANTA': 5, 'PEPSI': 4 },
'Ciclano': { 'SPRITE': 5, 'COCACOLA': 4, 'TUBAÍNA': 5 },
'Beltrano': {},
'Trajano': { 'GUARANÁ': 3, 'FANTA': 2, 'PEPSI': 1, 'COCACOLA': 4 }
}
relatorio_avaliadores(pesquisa2)
# posso inclusive passar o dicionário diretamente
relatorio_avaliadores({
'Maria': { 'FANTA': 3 },
'José': { 'COCACOLA': 5, 'SPRITE': 2 },
'Fulano': { 'GUARANÁ': 4, 'PEPSI': 2, 'COCACOLA': 4 }
})
Note that I can pass any dictionary to the function, and it works the same way (so it gets more generic, rather than depending on an external variable to it).
I also showed another way to iterate through the dictionary, returning the name and notes at the same time, and sorting through the key: items() returns keys and values in tuples, and in the sort I say to use the first element of the tuple, which is the dictionary key (use itemgetter(0) to indicate that I will use the first element - remember that the indexes start at zero, so I used itemgetter(0)).
And as recalled in the comments, if you don’t have control over the structure, you can convert its initial structure to the one I suggested above:
pesquisa = {'PEDRO': ['FANTA',5,'PEPSI',4],'ANA': ['SPRITE',5,'COCACOLA',4]}
pesquisa = { nome: dict(zip(notas[::2], notas[1::2])) for nome, notas in pesquisa.items() }
That is, for each reviewer, I take the list of notes and turn it into the dictionary. The trick is to use the Slices [::2] (takes the even indexes of the list) and [1::2] (picks up the odd indices). Read here to better understand how this syntax works.
It is worth saying how to convert into
dict, since we don’t know if it’s in control of the AP, anything like:d = {i: dict(zip(pesquisa[i][::2], pesquisa[i][1::2])) for i in pesquisa}– Miguel
@Miguel Boa, updated the reply, thank you!
– hkotsubo
You’re welcome @hkotsubo (:
– Miguel