There is no particular need for this to be a class. While the reading of the file and the writing of the file are coupled, IMO this is not yet enough to make it into a class.
What is especially confusing is that you use members even for local variables which are not needed in the other methods.
Now, first, your reading of the file can be greatly simplified:
def read_password_file(file_name="passwords.txt"):
with open(file_name) as f:
return {key: password for key, password in map(str.split, f)}
This also allows using a different file than the default. It uses a dictionary comprehension.
The generation of the random passwords should be separate from the CLI interface (in case you want to change one without the other). The generation itself can also be simplified by using the string
module:
import random
from string import ascii_lowercase, ascii_uppercase, digits, punctuation
ALLOWED_CHARS = ascii_lowercase + ascii_uppercase + digits + punctuation
def generate_random_pass_word(length=14, allowed_chars=ALLOWED_CHARS):
return "".join(random.choices(allowed_chars, k=length)
This also uses the random.choices
function introduced in Python 3.6.
Your saving and retrieving from the passwords dictionary can become this:
import hashlib
def save_password(passwords, password, file_name="passwords.txt"):
if password is None:
print('First generate a password')
print('to save the generated pass word give it a name')
name = hashlib.md5((input().encode('utf-8'))).hexdigest()
if name in passwords:
print('your key password already exists!')
else:
with open(file_name, 'a') as f:
f.write(f"{name} {password}\n")
passwords[name] = password
print('password stored')
def read_password(passwords):
print('to read the generated pass word type its name')
name = hashlib.md5((input().encode('utf-8'))).hexdigest()
if names in passwords:
print(passwords[name])
else:
print('we are sorry your password is non existent')
Note that I call your self.myPass
what it is, a simple name. It is not really a password (you could look it up in the file and use a rainbow table to get the cleartext) and even the context of having to think of a good password to store your good password seems ridiculous (do you use this password generation function to generate this password? What password do you use to store that password?).
And finally, your main
function, which has the user interface:
def main():
pass, action = None, None
passwords = read_password_file()
print('perform one of the actions')
while action != 'break':
action = input('new action please\n')
if action == 'generate':
print('determine your generated password length, We recommend above 14 characters')
length = int(input())
pass = generate_random_pass_word(length)
print('generated:', pass)
elif action == 'read':
read_password(passwords)
elif action == 'save':
save_password(passwords, pass)
else:
print(action + 'is not a valid action')
if __name__ == "__main__":
main()
print('fin')
Note that I put the calling of main
under a if __name__ == "__main__":
guard to allow importing from this script from another script.