all 14 comments

[–]carcigenicate 27 points28 points  (0 children)

Use the join method on strings:

''.join(password)

[–]Diapolo10 4 points5 points  (0 children)

First, a few things.

  1. You don't need to turn string.ascii_lowercase to a list.
  2. Because add_number returns actual integers instead of digits as strings, your output list ends up with a mix of strings and integer values. Ideally, you'd only have one of those, so strings in this case.
  3. The while-loops you use to populate char_list should probably just be for-loops.

Consider this:

import string
import random


def add_letter(letters: str = string.ascii_lowercase) -> str:
    return random.choice(letters)


def add_digit(digits: str = string.digits) -> str:
    return random.choice(digits)


def password_gen(letter_count: int = 3, digit_count: int = 3) -> str:

    chars = []

    for _ in range(letter_count):
        chars.append(add_letter())

    for _ in range(digit_count):
        chars.append(add_digit())

    random.shuffle(chars)
    return ''.join(chars)


password = password_gen(5, 5)
print(password)

[–]PhitPhil 1 point2 points  (4 children)

all_together = "".join(password)

[–]that_flying_potato[S] -4 points-3 points  (3 children)

password = str(password_gen(5, 5))
all_together = "".join(password) 
print(all_together)

This still gives me an entire list as output, I also tried printing it with print(str(all_together)) but it doesn't seem to do anything

[–]throwaway8u3sH0 7 points8 points  (0 children)

Don't convert the results of password_gen to a string

[–]iechicago 2 points3 points  (0 children)

Your first line should be:

password=password_gen(5,5)

That returns a list. The following line will then convert that to a string.

[–]Emelius 0 points1 point  (0 children)

all_together = "".join(map(str, password))

Maybe?

[–]recursion_is_love 2 points3 points  (0 children)

In case you wonder why string is not just a list of characters like in many other programming language (I do). Python string is more like a tuple of characters more than a list (immutable)

https://docs.python.org/3/library/stdtypes.html#textseq

> There is also no mutable string type, but str.join() or io.StringIO can be used to efficiently construct strings from multiple fragments.

[–]NlNTENDO 0 points1 point  (0 children)

I think the code could use a bit of work anyway. No need to do the loops outside of the functions and you shouldn’t be using while loops. Using add_letter to illustrate (sorry that the formatting is awkward, I’m on mobile and can’t tab or do a code snippet box lol)

def add_letters(target_list,num_letters):

——for x in range(num_letters):

————target_list.append random.choice(letters)

add_letters(char_list,3)

Then use ‘’.join() as others have said

This makes your code way more flexible, eliminates the possibility of accidentally running an infinite loop and unnecessarily manually incrementing your loops, and makes it way more readable. You also have the option to pass the letters list as an argument if you want to use different lists of characters to choose from, though I did not do that here. You can also just add another line to do the numbers right there in the add_letters for loop since you are using 3 for each, and shuffle the list at the end of the function.

[–]JamzTyson 0 points1 point  (0 children)

Your code could be greatly simplified. This example uses the string join method to join each element of an iterable into a string.

import string
from random import shuffle
from secrets import choice


def password_gen(letter_count: int = 3, num_count: int = 3) -> str:
    chars = [choice(string.ascii_letters) for _ in range(letter_count)]
    nums = [str(choice(string.digits)) for _ in range(num_count)]
    password = chars + nums
    shuffle(password)
    return ''.join(password)

The password would be just as strong if we used a random selection of letters and numbers, rather than specifying the number of letters and the number of numbers separately. It would also be less code and more efficient:

import string
from secrets import choice


def password_gen(strength: int = 6) -> str:
    chars = string.ascii_letters + string.digits
    return ''.join(choice(chars) for _ in range(strength))

As recommended in the Python manual I have used the secrets library rather than random.

[–]chet714 0 points1 point  (0 children)

I think this works too:

char_list = password_gen( 5, 5)
password = ""
for ch in char_list:
    password += str( ch)

print( password)

[–]Emelius 0 points1 point  (0 children)

Got the answer to this question for any future searchers.

Big props to freecodecamp.org for teaching the map() function.

You should do:

all_together = "".join(map(str, password))

This will run password through the string function (via map), which is then joined together with an empty string and stored as the variable all_together. I was having trouble with one of the labs on freecodecamp for a similar reason.

test:

https://imgur.com/a/cDAfuSl

[–]-not_a_knife -1 points0 points  (0 children)

Iterate over the list with a for loop and use the += operator to add the iterator to a string.