Hello everyone,
I just started learning python yesterday, and I created a function creating a random password with small letters and some numbers.
mdp = ['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', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
def m(r):
for z in range(r):
print(choice(mdp), end='')
print(m(8))
02kqpvqnNone
Why is this "None" printing at the end of the password?

You're executing print()
in two locations.
The first is inside the function. That's where you print the 8 characters.
But then outside the function (on line 7) you print the return value from the function. As the function doesn't return anything explicitly, it defaults to returning None
, and that is printed.
(Feb-08-2021, 08:17 AM)bowlofred Wrote: [ -> ]You're executing print()
in two locations.
The first is inside the function. That's where you print the 8 characters.
But then outside the function (on line 7) you print the return value from the function. As the function doesn't return anything explicitly, it defaults to returning None
, and that is printed.
Thank you a lot! Just took the second print away and now it works
m(8)
! I'll remember this now

(Feb-08-2021, 08:21 AM)thortank Wrote: [ -> ]Just took the second print away and now it works
The better approach is to construct the desired string inside the function and then make your function return this string. Then print the returned value outside the function. This way it is reusable - e.g. you can print, or bind to a name for later use. At the moment your function just prints something - not great use.
(Feb-08-2021, 08:49 AM)buran Wrote: [ -> ] (Feb-08-2021, 08:21 AM)thortank Wrote: [ -> ]Just took the second print away and now it works
The better approach is to construct the desired string inside the function and then make your function return this string. Then print the returned value outside the function. This way it is reusable - e.g. you can print, or bind to a name for later use. At the moment your function just prints something - not great use.
What do you mean? I don't really understand... Can you please make an example if you have time?
"""
Programm to output random lower case ascii characters + digits
"""
import string
from random import choice, choices
MDP = string.ascii_lowercase + string.digits
def random_chars(length):
chars = []
for _ in range(length):
chars.append(choice(MDP))
return "".join(chars)
def random_chars_easy(length):
return "".join(choices(MDP, k=length))
if __name__ == "__main__":
print(random_chars(12))
You should visit the documentation:
chars = ["a", "b", "c"]
print("".join(chars))
print("-".join(chars))
Output:
abc
a-b-c
from random import choices # plural
chars = "abcdefgh1234"
print(choices(chars, k=5))
Output:
['4', 'a', 'd', 'e', 'e']
I hope that are enough examples to understand the code.
Another hint:
If you make a
function
without any
return
statement inside, the object
None
is returned implicit. For example
print
was in Python 2 a statement. Now since long time,
print
is a
function
. Also the print function return a
None
.
That's why you got a
None
.
def foo():
pass
print(foo())
Output:
None
(Feb-08-2021, 10:54 AM)DeaD_EyE Wrote: [ -> ]"""
Programm to output random lower case ascii characters + digits
"""
import string
from random import choice, choices
MDP = string.ascii_lowercase + string.digits
def random_chars(length):
chars = []
for _ in range(length):
chars.append(choice(MDP))
return "".join(chars)
def random_chars_easy(length):
return "".join(choices(MDP, k=length))
if __name__ == "__main__":
print(random_chars(12))
You should visit the documentation:
chars = ["a", "b", "c"]
print("".join(chars))
print("-".join(chars))
Output:
abc
a-b-c
from random import choices # plural
chars = "abcdefgh1234"
print(choices(chars, k=5))
Output:
['4', 'a', 'd', 'e', 'e']
I hope that are enough examples to understand the code.
Another hint:
If you make a function
without any return
statement inside, the object None
is returned implicit. For example print
was in Python 2 a statement. Now since long time, print
is a function
. Also the print function return a None
.
That's why you got a None
.
def foo():
pass
print(foo())
Output:
None
I think I understand the idea, but in the code, you've written, there are still some things I don't fully understand.
For example the:
def random_chars(length):
chars = []
for _ in range(length):
chars.append(choice(MDP))
return "".join(chars)
What is the
chars.append
and
return "".join
? What is it used for?
There are also the
if __name__ == "__main__":
... What is
__name__
and
"__main__"
?
Sorry for that many questions

Quote:What is the chars.append and return "".join? What is it used for?
chars
is a list.
chars = [] # <- empty list
chars.append(element)
is the method to append an element to a list.
You should learn more about list, tuple, dict, set.
After creation the list is empty and then for each iteration a new element is append to the list.
Then you have a list with many chars. To "convert" the list into a str, the str.join method is used.
"" # < this is an empty str literal
# and you can access the methods of str with a . dot
abc_as_str = "".join(["a", "b", "c"])
The
""
is an empty string, the
join
method uses the empty
str
to concatenate the strings in the sequence (list).
Quote:There are also the if __name__ == "__main__":... What is __name__ and "__main__"?
If you run your program with:
python3 your_program.py
Then
__name__ == "__main__"
.
If you import your code in another source file, then
__name__
is different.
This prevents accidentally program execution, if you import it.
For example, you can name the file foo.py. Then you import from another source file
foo.random_chars
.
If you've not used the __name__ pattern, then the code below is executed and the result is printed in console during import. Not good.