Gerald
Gerald

Reputation: 13

Why does my for loop stop working when it shouldn't?

I'm learning python and new to coding. I am trying to code a password generator which picks random letters, symbols and number and combining in random order but it doesn't work properly.

You can see that i have tried to add all random elements into one list and randomize again in it. However it stops at some point, for example if we answer as 2 for each question it will pick 6 random elements in total and it adds all these into one list. After that it picks 1 on element, adds it to password and deletes from list. After 6 times, password should be ready and code should stop because there is no more elements in list.

However, it should create 6 figure password but it stopped at 3 figures and there is still 3 element in list.

Example:

Welcome to the PyPassword Generator!
How many letters would you like in your password?
2
How many symbols would you like?
2
How many numbers would you like?
2
Output:
['f', 'L', '$', '&', '0', '9']
$f&
['L', '0', '9']

Code is here:

import random
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',               's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
symbols = ['!', '#', '$', '%', '&', '(', ')', '*', '+']

print("Welcome to the PyPassword Generator!")
nr_letters= int(input("How many letters would you like in your password?\n")) 
nr_symbols = int(input(f"How many symbols would you like?\n"))
nr_numbers = int(input(f"How many numbers would you like?\n"))

password = []
new_password = ""

for letter_count in range(0,nr_letters):
  random_letter = random.choice(letters)
  password.append(random_letter)

for symbol_count in range(0,nr_symbols):
  random_symbol = random.choice(symbols)
  password.append(random_symbol)

for mumber_count in range(0,nr_numbers):
  random_number = random.choice(numbers)
  password.append(random_number)

print(password)

for element in password:
  random_element = random.choice(password)
  new_password = new_password + random_element
  password.remove(random_element)
  print(password)
  print(new_password)

Upvotes: 0

Views: 89

Answers (3)

Marco F.
Marco F.

Reputation: 705

Do not change the list while it is iterating. Try this:

for element_no in range(len(password)):
  random_element = random.choice(password)
  new_password = new_password + random_element
  password.remove(random_element)
  print(password)
  print(new_password)

For details: Strange result when removing item from a list while iterating...

Upvotes: 2

amash
amash

Reputation: 1

Notice that within the last loop, you are removing elements from the list you are iterating over. This means that with every iteration the list get shorter. In your example, by the time you get to the fourth element, the list only has 3 items in it, so it stops.

One way you can do it without a for loop at all is replace the last loop with:

random.shuffle(password) # re-orders the list in place, returns None
new_password = ''.join(password)
print(new_password)

Upvotes: 0

Christoph
Christoph

Reputation: 1048

The issue you're facing is caused by the way you're trying to generate the randomized password by removing elements from the list password.

Also your code could simplified to this =)

import random, string

print("Welcome to the PyPassword Generator!")
password = ''.join(random.choices(string.ascii_letters, k=int(input("How many letters? "))) + 
                   random.choices('!#$%&()*+', k=int(input("How many symbols? "))) + 
                   random.choices(string.digits, k=int(input("How many numbers? "))))
print("Your password is:", ''.join(random.sample(password, len(password))))

Upvotes: 1

Related Questions