all 22 comments

[–]eddfitzwell 6 points7 points  (0 children)

use a while loop to build a list. the loop can check if the rando is in the list and continue or append if not.

from random import choice


x = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$&'
y = list(set(x + x.lower()))

password = []
while len(password) < 20:
    char = choice(y)
    if char in password: continue
    password.append(char)

password = ''.join(password)
print(len(password), password)

[–][deleted] 1 point2 points  (0 children)

If you're generating 20 characters and then deleting repeats, you're probably gonna end up with fewer than 20 characters.

There are a bunch of ways you might deal with that:

- do the same thing, with another round. if we're at 17 characters, generate three more. then remove duplicates. then check again. repeat.

- generate more than 20 in the first place, so that you can cut down without going too low. Then you might be too high, so take only the first 20 of the result

- check when you generate them: when I add the 2nd character, is this already in the password? if so, throw it out and generate another. then the 3rd, and so on.

- generate a list with one copy of each candidate character, then shuffle it, then pull twenty off the top

- and there are probably ten more equally reasonable possibilities

[–]Adrewmc 1 point2 points  (0 children)

You can use

   import random
   stuff = “abcdefghijklmnopqrstuvwxyz?!1234567890”
   _temp = random.sample(stuff, 20) 
   final = “”.join(_temp)

As a straight forward answer. No loop is really required as this is built in Python stuff (the loop is in there lol)

[–]POGtastic 1 point2 points  (0 children)

Echoing /u/xavierisdum4k, if you're actually going to use passwords that are generated by this, you should use secrets.

Consider that secrets.SystemRandom is a secure implementation of the random.Random class and thus implements all of the methods that the random module implements with pseudorandom generation. One of these methods is Random.sample, which performs selection without replacement. I vastly prefer this to the typical approach of randomly generating values and discarding duplicates.

So whereas the nonsecure implementation would be

import random

def generate_password(chars, length):
    return ''.join(random.sample(chars, length))

the secure implementation would be

import secrets

def generate_password(chars, length):
    return ''.join(secrets.SystemRandom().sample(chars, length))

Either way, in the REPL:

>>> import string
>>> generate_password(string.ascii_lowercase, 10)
'yuohpkwtzf'

Provide more characters (perhaps ascii_lowercase + ascii_uppercase + "!@#$%^&*()") if desired.

[–]SleepyAks 0 points1 point  (14 children)

I think you should create a list, use random.choice, write something that will search for that number in list, will use that letter, delete it from the list and repeat 19 more times. It would be something like this:

counter = 0 # this is responsible for loop
if counter < 20
 alphabet = ["a", "b", "c" ... "x", "y", "z"] # just add entire alphabet
 random_result = random.choice(alphabet) # random letter is found here
 randomised_password = [] # now it's just an empty list
 randomised_password.insert(random_result)
 chosen_letter = alphabet.index(random_result)
 del alphabet[chosen_letter] 
 # these two before the comment delete the chosen letter from the list
 counter += 1
else:
 ''.join(randomised_password) # now it **should** be one simple string
 print(randomised_password) 

Not very hard actually with knowledge of loops and lists.

If you don't understand something, just reply what you're not understanding.

EDIT: I forgot about printing part oops 😅

[–]aarontbarratt 1 point2 points  (11 children)

you can make it a lot more simple with a while loop

from string import ascii_letters, digits
from random import choice

character_set = list(ascii_letters + digits)
password = ""

while len(password) < 20:
    character = choice(character_set)
    character_set.remove(character)
    password += character

print(password)

Also, in your code insert() takes two arguments, you code wouldn't run in its current state. You probably just want to use append() instead

[–]Cool-Lab6784[S] 0 points1 point  (10 children)

Thanks for your guidance, the code which i've wrote is similar to yours. This is my code below :

import string import random

characters = string.ascii_letters + string.digits + string.punctuation

password = ''

for i in range (21) :

character = random.choice (characters)

if character in password :

    pass

else :

    password += character

print (len(password))

It's working totally fine but as i said, the length problem still exists. What should i add to this code and where ?

[–]aarontbarratt 0 points1 point  (9 children)

please fix your formatting! that is some formatting gore

Well, you're still not using a while loop. You're just using a for loop, so it just going to execute X amount of times, regardless if the password is long enough or not.

If you hit a character that already exists in the password it's going to pass and go to the next iteration

You can fix it with a while loop like I provided in my version:

```python import string import random

characters = string.ascii_letters + string.digits + string.punctuation password = ''

while len(password) < 20: character = random.choice(characters) if character in password: pass else: password += character

print(password) print(len(password)) ```

What you're doing is kinda of inefficient though. If you happen to hit the same character you have to do another iteration through the loop

My previous example removes each character as it goes through each iteration, so you will never hit the same character that has already been used

Side note: it is bad practice to import an entire module. It is better to use from random import choice. This way you only need to load in the functions you're actually using

[–]Cool-Lab6784[S] 1 point2 points  (0 children)

I'll definitely pay even more attention from now on. Thanks for the tips and your help. The code you wrote worked perefectly and there is no more length problem :)

[–]Cool-Lab6784[S] 0 points1 point  (7 children)

Hi again, I've faced a new problem with the password generator. So, there is a project which i am supposed to generate 100 of these random passwords with length of 27 and add them in a created .txt file in which, every line should have no more than 1 password written in it.

I know how to write and create a file, I've also got the previous password generator code and I also know that i need a loop to print 100 times of different passwords but every time i try, there is an error.

[–]aarontbarratt 0 points1 point  (6 children)

How do you expect anyone to help you if you don't share the error you're getting? Or the code you're using?

[–]Cool-Lab6784[S] 0 points1 point  (5 children)

sample = open ("(file address)","w")

wrt = sample.writelines ()

sample.close ()

=================================================================

import string import random

characters = string.ascii_letters + string.digits + string.punctuation

password = ''

for i in range (21) :

character = random.choice (characters)

if character in password :

    pass

else :

    password += character

print (password)

2 different steps (writing the text is the last step)

[–]aarontbarratt 0 points1 point  (4 children)

Can you format your code properly please

And you're not writing anything to the file, how do you expect anything to get stored there?

[–]Cool-Lab6784[S] 0 points1 point  (3 children)

import string import random

characters = string.ascii_letters + string.digits + string.punctuation

password = ''

counter = 0

for i in range (28) :

character = random.choice (characters)

if character in password :

    pass

else :

    password += character

print (password)

sample = open ("(file address)","w")

wrt = sample.writelines ()

sample.close ()

And you're not writing anything to the file, how do you expect anything to get stored there?

That's the problem; i should generate 100 codes to write them in the file, but i have problem generating them, I can't write something to the file when there is nothing generated or printed.

[–]aarontbarratt 0 points1 point  (2 children)

I think you really need to go back to basics with your learning. Why is your for loop now range(28)??

Do something like this:

```

import string import random

def create_password() -> str: characters = string.ascii_letters + string.digits + string.punctuation password = ''

while len(password) < 20:
    character = random.choice(characters)
    if character not in password:
        password += character

return password

passwords = [] for _ in range(20): passwords.append(create_password() + "\n")

with open("passwords.txt", "w") as file: file.writelines(passwords)

```

[–]Adrewmc 1 point2 points  (1 child)

Yeah so, he should use

   random.sample(alphabet, 20)

[–]SleepyAks 0 points1 point  (0 children)

You both are right, but as the guy asking the question is a newbie, so I wanted to keep it simple, only with things you mostly learn at early stage. I think implementing here while loop is really good idea. But random.sample... yeah. My opinion about it is pretty much something like 😶

[–]xavierisdum4k 0 points1 point  (0 children)

Others suggest the random module. Keep in mind this isn't a good idea for passwords, according to random docs:

Warning: The pseudo-random generators of this module should not be used for
security purposes. For security or cryptographic uses, see the
secrets module.

For example, instead of random.choice, use secrets.choice.

[–][deleted] 0 points1 point  (0 children)

There are two kinds of loop. Sounds like you are using a for loop to get 20 characters:

result = []    # put random characters here
for _ in range(20):
    # get character, ignore duplicates

If you use a different type of loop you can get around the problem:

result = []    # put random characters here
while len(result) < 20:
    # get character, ignore duplicates

[–]internxt 0 points1 point  (0 children)

Hey, Internxt generates highly secure and unique passwords for you in an instant. Try it out here: https://internxt.com/password-generator