Insert names to a list depending on their value

Asked

Viewed 177 times

2

I’m trying to make a draw code, the user inserts the value to be donated and your name.

Let’s assume that Bia donates 10 real, Bia’s name has to appear 1 time on the list. And let’s assume that Samuel donates 30 real, his name would have to appear 3 times on the list.

Ex: ['Bia', 'Samuel', 'Samuel', 'Samuel'] 

And so, successively.

I’m not able to separate the user name in a list, it stays like this in the terminal:

inserir a descrição da imagem aqui

And my code is like this:

valor = int(input('Digite o valor que você deseja doar: '))
nome = input('Qual o seu nome? ')

if valor == 10:
    total = 1
    totalNome = [nome * 1]
    print('Você vai concorrer {} vez.'.format(total))
elif valor == 20:
    total = 2
    totalNome = [nome * 2]
    print('Você vai concorrer {} vezes.'.format(total))
elif valor == 30:
    total = 3
    totalNome = [nome * 3]
    print('Você vai concorrer {} vezes.'.format(total))

nomes = []
nomes.append(totalNome)
print(nomes)
  • Hello guys, sorry, I already made the correction.. First time using here, I’m still getting acquainted. But I’ve already edited and put as requested!

  • @hkotsubo I had not committed myself on this, I can use the Random.shuffle in the same names list, right?

  • I want to do the following, let’s assume that Samuel donated 40 real. Samuel’s name has to appear 4 times on the list. If Bia donated 20, her name has to appear 2 times. I need to list some "donors" with their respective donations. To draw lots with these people.

  • Considering that the name of the donor will appear 1 time for every 10 reais you donate. Da para entender? I don’t know if I expressed myself well

  • Then re-edit the question and put it all there. In the current code it is not clear that it was to put multiple names.

  • @hkotsubo went badly :( edited again.

  • Ah, what if the value is 25? 32? 49? Will round? Or do you only accept multiple values of 10 (like 10, 20, 30, etc)?

  • @hkotsubo Values will be (10, 20, 30).

Show 3 more comments

4 answers

2


When you do [ algo ], is creating a list (because of [ ]), with a single element (algo).

In your case, this algo is nome * 3, which is basically the string nome "multiplied by 3". In Python, when you "multiply" a string by a number, the result is another string, with its contents repeated several times. That is, if nome for a string "Samuel", then nome * 3 will be the string "Samuelsamuelsamuel".

Therefore, you are creating a list containing only one element: a string with the nome repeated several times.

If the idea is to create a list with the same name several times, you could do [ nome ] * 3 (the list [ nome ] contains the name once, and by "multiplying" the list by a number, you create a list with this element repeated several times), which results in a list with 3 elements (all equal to nome).

Another point is that at the end you add this list into another list, but it doesn’t seem to be what you want.

What would have to be done is to have a single list, and you just insert it into it. Something like this:

nomes = []

for _ in range(3): # lê 3 nomes (pode mudar para quantos precisar)
    # lê os dados e atualiza os nomes
    valor = int(input('Digite o valor que você deseja doar: '))
    nome = input('Qual o seu nome? ')
    total, resto = divmod(valor, 10)
    if resto == 0 and total > 0:
        print(f'Você vai concorrer {total} vez{"es" if total > 1 else ""}.')
        nomes.extend([ nome ] * total)
    else:
        print('valor inválido, deve ser múltiplo de 10 e maior que zero')

print(nomes)

Since the values should be multiples of 10, I used divmod to take the result of the division by 10 and the rest of this division. Thus, if the rest is not zero, the value is invalid.

Then I use [ nome ] * total to create the list with the repeated name several times, and use extend to add these elements to the list nomes.

I put in a loop to read several names, but then you can adapt accordingly.


Then you can shuffle with random.shuffle, if you want:

from random import shuffle
shuffle(nomes)

Although, to draw a random amount, just use random.choice (maybe you don’t even have to shuffle, since choice will choose an item from the list randomly, and whatever position they are in):

from random import choice
sorteado = choice(nomes)
  • Boy, I tested it, but it doesn’t look like what the guy described, I can post a solution?

  • 1

    @Danizavtz I understood that was it. If you understood something else, answer there too :-)

  • 1

    @hkotsubo thank you very much, I was able to learn a lot from your explanation. And if it is not multiples of 10, just I remove the divmod?

  • @hkotsubo, published mine, I will put the references of the lib.

  • 1

    @Samuelteixeira If it is not to accept only multiples of 10 (and any value), it depends on how the logic would be. But you could do, for example, total = valor // 10 (with two bars, which already rounds down, that is, values of 20 to 29 would give a total of 2), and would not need to test the resto. Or you can use valor / 10 (with a bar) and use some function of module math (as ceil or floor) to round up according to what you need

  • @hkotsubo thank you very much, my dear. you helped me too much!!!!!!!

Show 1 more comment

1

One way to solve this problem is by inserting people directly into an array and then drawing lots.

Follow an example:

from random import choice

def inserirNoSorteio(lista, nome, qtd):
    for i in range(qtd):
        lista.append(nome)
    return lista


repetir = True nomes = []

while repetir:
    valor = int(input('Digite o valor que você deseja doar: '))
    nome = input('Qual o seu nome? ')

    if valor < 20:
        total = 1
        inserirNoSorteio(nomes, nome, total)
        print('{} vai concorrer {} vezes.'.format(nome, total))
    elif valor < 30:
        total = 2
        inserirNoSorteio(nomes, nome, total)
        print('{} vai concorrer {} vezes.'.format(nome, total))
    else:
        total = 3
        inserirNoSorteio(nomes, nome, total)
        print('{} vai concorrer {} vezes.'.format(nome, total))
    
    
    inserirMaisPessoas = input('Deseja adicionar mais pessoas? (s/n)')
    if inserirMaisPessoas[0].lower() == 'n':
        repetir = False
     print('Sorteando o ganhador...') sorteado = choice(nomes) print(nomes) print('O ganhador foi: {}'.format(sorteado))

Explaining the code

In my example I used the module function Choice random python. This function will return a random element from a non-empty list. If the list is empty the error is launched IndexError.

My logic is based on the code that was provided, but I made some assumptions regarding the values that the user can donate. For example: if I donate values less than 20, I will always add the 1x name, if it is greater than or equal to 20, I enter it in the list of the draw 2x, if it is greater than 30 only 3x, then if the user donates 50, its name will be inserted 3x.

For this we leave the user in a donation insertion loop and name.

After the user no longer wants to enter people in the draw, the draw is made with the people in the list. I am displaying the array of names (people in the draw), just for debug purposes.

  • True, it has a bug. @hkotsubo

  • @hkotsubo, corrected by.

0

Simplistically, there is a more dynamic hint to create this draw:

valor = int(input('Digite o valor que você deseja doar: '))
nome = input('Qual o seu nome? ')
nomes = []
valor //= 10  # Equivalente à valor = valor // 10, que no caso retorna a parte inteira da divisao
[nomes.append(nome) for _ in range(valor)]
print("Voce vai concorrer a {} sorteio(s)".format(valor))
print(nomes)

Result achieved:

Digite o valor que você deseja doar: 32
Qual o seu nome? Samuel
Voce vai concorrer a 3 sorteio(s)
['Samuel', 'Samuel', 'Samuel']

0

Using List Comprehensions (List Comprehension)

lista = ['Bia']

#considerando que cada nome custe 10

valor = input('Valor que deseja doar: ')
qtde = int((int(valor) / 10))
nome = input('Qual o seu nome? ')

#Commpressão de lista(List comprehension)
#Vale a pena dar uma pesquisada sobre o assunto mas adianto que usando LC existe uma 
#melhora de perfomance consideravel, fora o código limpo.

listaTemporaria = [nome for x in range(qtde)]
lista.extend(listaTemporaria) # equivalente a -> lista = lista + listaTemporaria

print(lista)

Browser other questions tagged

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