I am trying to make a program that gets a password and a username using a tkinter entry, and then saves it on an external file. Here is what I have got so far:
def validateLogin(username, password):
filename = input("What is your first name?: ")
c = open(filename, "w");
print("username entered :", username.get())
print("password entered :", password.get())
c.write(username)
return
. That is just the part that I am having trouble with at the moment.
c.write(username) attempts to write an object of type StringVar, but files opened with c = open(filename, "w") only work with text, a.k.a. str.
To extract the string from a StringVar, use get, as you were using earlier in your code:
c.write(username.get())
c.close() # don't forget to close the file
Related
I am making a small simple password manager in python. I have the functions of creating an account which has 3 inputs, Username, Password, and Website. I have a function to view all the accounts which shows the contents of the file info.txt where all that information goes. Im trying to create a function to delete an entry but im not sure how to make the function delete all the lines of information associated with the Username. I want an input asking "Which account to delete" you put the username, and it will delete all information associated with the username in info.txt
Code:
import os.path #Imports os module using path for file access
def checkExistence(): #Checking for existence of file
if os.path.exists("info.txt"):
pass #pass is used as a placeholder bc if no code is ran in an if statement and error comes.
else:
file = open("info.txt", "w") #creates file with name of info.txt and W for write access
file.close()
def appendNew():
#This function will append a new password in the txt file
file = open("info.txt", "a") #Open info.txt use a for appending IMPORTANT: opening a file with w for write will write over all existing data
userName = input("Enter username: ")
print(userName)
os.system('cls')
password = input("Enter password: ")
print(password)
os.system('cls')
website = input("Enter website: ")
print(website)
os.system('cls')
print()
print()
usrnm = "Username: " + userName + "\n" #Makes the variable usrnm have a value of "Username: {our username}" and a new line
pwd = "Password: " + password + "\n"
web = "Website: " + website + "\n"
file.write("----------------------------------\n")
file.write(usrnm)
file.write(pwd)
file.write(web)
file.write("----------------------------------\n")
file.write("\n")
file.close()
def readPasswords():
file = open("info.txt", "r") #Open info.txt with r for read
content = file.read() # Content is everything read from file variable (info.txt)
file.close()
print(content)
checkExistence()
while True:
choice = input("Do you want to: \n 1. Add account\n 2. View accounts\n 3. Delete account\n")
print(choice)
if choice == "1":
os.system('cls')
appendNew()
elif choice == "2":
os.system('cls')
readPasswords()
elif choice == "3":
os.system('cls')
else:
os.system('cls')
print("huh? thats not an input.. Try again.\n")
I tried making a delete account function by deleting the line which matched the username. My only problem is that it only deletes the line in info.txt with the username, but not the password and website associated with that username.
Firstly, you're using the wrong tool for the problem. A good library to try is pandas, using .csv files (which one can think of as pore program oriented excel files). However, if you really want to use the text file based approach, your solution would look something like this:
with open(textfile, 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
# The above makes a list of all lines in the file without \n char
index = lines.index(username)
# Find index of username in these lines
for i in range(5):
lines.pop(index)
# Delete the next five lines - check your 'appendNew' function
# you're using five lines to write each user's data
print(lines)
f.write("\n".join(lines))
# Finally, write the lines back with the '\n' char we removed in line 2
# Here is your readymade function:
def removeName(username):
with open("info.txt", 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
try:
index = lines.index(username)
except ValueError:
print("Username not in file!")
return
for i in range(5):
lines.pop(index)
print(lines)
f.write("\n".join(lines))
# Function that also asks for username by itself
def removeName_2():
username = input("Enter username to remove:\t")
with open("info.txt", 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
try:
index = lines.index(username)
except ValueError:
print("Username not in file!")
return
for i in range(5):
lines.pop(index)
print(lines)
f.write("\n".join(lines))
# Usage:
removeName(some_username_variable)
removeName_2()
Again, this is a rather clunky and error prone approach. If you ever change the format in which each user's details are stored, your would have to change the number of lines deleted in the for loop. Try pandas and csv files, they save a lot of time.
If you're uncomfortable with those or you're just starting to code, try the json library and .json files - at a high level they're simple ways of storing data into files and they can be parsed with the json library in a single line of code. You should be able to find plenty of advice online about pandas and json.
If you're unable to follow what the function does, try reading up on try-except blocks and function parameters (as well as maybe global variables).
I am a beginner to Python have been trying to create a simple python menu. One of the options asks the user what user they want to search for. Each user will have a text file dedicated to them, and when the user types and searches for that user, it will search through a list of text files in a directory, and then it will print all of the user's details onto the program. I have managed to get my program to search through the text files to find the right user, but I am unsure of how to print the text file onto my program.
Code:
import os
from os import listdir
os.system("")
import glob
import os.path
menu()
option = int(input("\n" + "Enter your option: "))
while option !=0:
if option == 1:
dir_path = r'D:\My project'
for file in os.listdir(dir_path):
cur_path = os.path.join(dir_path, file)
if os.path.isfile(cur_path):
with open(cur_path, 'r') as file:
username = input("Enter a username: ")
if username in file.read():
print('user found')
#Here is where I want to print the contents of the text file that
#has been found
menu()
break
else:
print ("Invalid option")
I have tried to make the program print "username", "file" etc, but in doing so this only prevents the program from working, as it will think that anything I enter is an invalid option.
Any help would be really appreciated, thanks!
Try saving the file contents in a variable:
if os.path.isfile(cur_path):
with open(cur_path, 'r') as file:
contents = file.read()
username = input("Enter a username: ")
if username in contents:
After the first file.read(), the file object's position is at the end and nothing will be read in subsequent calls, unless you go back to the start with file.seek(0).
See Methods of File Objects for more details.
As an aside, pathlib might be a better fit than os.path.
I'm a beginner in Python and ran across an error. I am trying to create a programme that will take a username and password made by a user, write them into lists and write those lists to files. Here is some of my code:
This is the part where the user is creating a username&password.
userName=input('Please enter a username')
password=input('Please enter a password')
password2=input('Please re-enter your password')
if password==password2:
print('Your passwords match.')
while password!=password2:
password2=input('Sorry. Your passwords did not match. Please try again')
if password==password2:
print('Your passwords match')
My code works fine up until this point, where I get the error:
invalid file: <_io.TextIOWrapper name='usernameList.txt' mode='wt' encoding='cp1252'>.
I'm not sure why this error is being returned.
if password==password2:
usernames=[]
usernameFile=open('usernameList.txt', 'wt')
with open(usernameFile, 'wb') as f:
pickle.dump(usernames,f)
userNames.append(userName)
usernameFile.close()
passwords=[]
passwordFile=open('passwordList.txt', 'wt')
with open(passwordFile, 'wb') as f:
pickle.dump(passwords,f)
passwords.append(password)
passwordFile.close()
Is there any way to fix the error, or another way to write the lists to a file?
Thanks
You had the right idea, but there were a number of issues. When the user passwords do not match, normally you would prompt for both again.
The with block is designed to open and close your files, so there is no need to add a close at the end.
The script below shows what I mean, you will then have two files holding a Python list. So trying to view it will not make much sense, you will now need to write the corresponding read part to your code.
import pickle
userName = input('Please enter a username: ')
while True:
password1 = input('Please enter a password: ')
password2 = input('Please re-enter your password: ')
if password1 == password2:
print('Your passwords match.')
break
else:
print('Sorry. Your passwords did not match. Please try again')
user_names = []
user_names.append(userName)
with open('usernameList.txt', 'wb') as f_username:
pickle.dump(user_names, f_username)
passwords = []
passwords.append(password1)
with open('passwordList.txt', 'wb') as f_password:
pickle.dump(passwords, f_password)
usernameFile=open('usernameList.txt', 'wt')
with open(usernameFile, 'wb') as f:
In the second line usernameFile is a file object. The first argument to open must be a file name (io.open() also supports file descriptor numbers as ints). open() tries to coerce its argument to a string.
In your case, this results in
str(usernameFile) == '<_io.TextIOWrapper name='usernameList.txt' mode='wt' encoding='cp1252'>'
which is not a valid filename.
Replace with
with open('usernameList.txt', 'wt') as f:
and get rid of usernameFile completely.
i know how to save a users input to a text file but how do i encrypt it? here is what i have for saving a users input to text file. i tried f.encrypt("Passwords_log.txt" but had no results
import time
password1 = input("Please type a password: ")
print("Your password has passed the verification!")
time.sleep(1)
print("Saving and encrypting password...")
time.sleep(2)
f=open("Passwords_log.txt",'a')
f.write(password)
f.write('\n')
f.close()
print("Done!")
There are some Python packages worth checking out that deal with cryptography.
Cryptography
PyCrypto
A simple example from cryptography would be the following:
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt(b"A really secret message. Not for prying eyes.")
plain_text = cipher_suite.decrypt(cipher_text)
check out password hashing.
then i'd suggest you use https://pythonhosted.org/passlib/ or pycrypto; depending on what alorithm you choose.
this is just to store the encrypted password. to then encrypt data have a look at https://pypi.python.org/pypi/pycrypto/2.6.1.
I guess you want to get some sort of a hash for the password, but file objects have nothing to do with that. You may try to use base64 encoding (like here), or any other other algorithm of the kind.
Your code:
import time
import base64
password1 = raw_input("Please type a password: ")
print("Your password has passed the verification!")
time.sleep(1)
print("Saving and encrypting password...")
time.sleep(2)
f=open("Passwords_log.txt",'a')
password = base64.b64encode(password)
f.write(password)
f.write('\n')
f.close()
print("Done!")
You said, you tried base64 but it didn't work. Here is how you can make it work:
import base64
import time
password1 = input("Please type a password: ")
print("Your password has passed the verification!")
time.sleep(1)
print("Saving and encrypting password...")
time.sleep(2)
f=open("Passwords_log.txt",'a')
cr = base64.encodestring(password1)
f.write(cr)
f.write('\n')
f.close()
print("Done!")
This is not real encryption, I wouldn't recommend it for passwords, but since you said in your comment that you tried to use base64 and it didn't work, I thought I should show you how to use base64 in your code.
I have written two scripts Write.py and Read.py.
Write.py opens friends.txt in append mode and takes input for name, email ,phone no and then dumps the dictionary into the file using pickle.dump() method and every thing works fine in this script.
Read.py opens friends.txt in read mode and then loads the contents into dictionary using pickle.load() method and displays the contents of dictionary.
The main problem is in Read.py script, it justs shows the old data, it never shows the appended data ?
Write.py
#!/usr/bin/python
import pickle
ans = "y"
friends={}
file = open("friends.txt", "a")
while ans == "y":
name = raw_input("Enter name : ")
email = raw_input("Enter email : ")
phone = raw_input("Enter Phone no : ")
friends[name] = {"Name": name, "Email": email, "Phone": phone}
ans = raw_input("Do you want to add another record (y/n) ? :")
pickle.dump(friends, file)
file.close()
Read.py
#!/usr/bin/py
import pickle
file = open("friends.txt", "r")
friend = pickle.load(file)
file.close()
for person in friend:
print friend[person]["Name"], "\t", friend[person]["Email"] , "\t", friend[person]["Phone"]
What must be the problem, the code looks fine. Can some one point me in the right direction ?
Thanks.
You have to load from the file several times. Each writing process ignores the others, so it creates a solid block of data independent from the others in the file. If you read it afterwards, it reads only one block at a time. So you could try:
import pickle
friend = {}
with open('friends.txt') as f:
while 1:
try:
friend.update(pickle.load(f))
except EOFError:
break # no more data in the file
for person in friend.values():
print '{Name}\t{Email}\t{Phone}'.format(**person)
You have to call pickle.load once for each time you called pickle.dump. You write routine does not add an entry to the dictionary, it adds another dictionary. You will have to call pickle.load until the entire file is read, but this will give you several dictionaries you would have to merge. The easier way for this would be just to store the values in CSV-format. This is as simple as
with open("friends.txt", "a") as file:
file.write("{0},{1},{2}\n".format(name, email, phone))
To load the values into a dictionary you would do:
with open("friends.txt", "a") as file:
friends = dict((name, (name, email, phone)) for line in file for name, email, phone in line.split(","))