Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why is it printing "None"?
#1
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? Think
Reply
#2
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.
buran likes this post
Reply
#3
(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 Big Grin
Reply
#4
(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.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
(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?
Reply
#6
"""
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
buran likes this post
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#7
(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 Shocked
Reply
#8
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.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020