Python Forum
trouble writing to file after while loop - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: trouble writing to file after while loop (/thread-1443.html)

Pages: 1 2 3


trouble writing to file after while loop - Low_Ki_ - Jan-04-2017

I'm trying to write a register form for account creation. When using a while loop to check for username matches I notice the loop gets ran through multiple times therefore appending to the file multiple times. The file used is a simple text file containing a simple list of usernames and passwords. All I want is for the loop to check if the username input matches any username in the file, if so then it should prompt for a new username to be entered and then check if there is a match on that username. If there is no match then it should continue to let the user know the account was created and append the username and password to the end of the file.
###################################
########## Register File ##########
###################################

# Open usrdata for read to check for username, pw match########
usrinfile = open("usrdata", 'r')

usrdatalist = [] # Create a list to check

for line in usrinfile:
   un, pw= (line.split(','))
   usrdatalist.append([un, pw])
# Close file
usrinfile.close()
###############################################################

# Get information from user
username = input("Enter a username: ")
password = input("Enter a password: ")

# Check if username already exists
usroutfile = open("usrdata", 'a')
for name in usrdatalist:
   while (name[0] == username):
       username = input("Name taken, enter a new name: ")
   if (name[0] != username):
       print("Account creation sucessful!")
   usroutfile.write(username + "," + password + '\n')
usroutfile.close()



RE: trouble writing to file after while loop - Low_Ki_ - Jan-04-2017

Wall ok so I think I'm slowly figuring it out? I've made some changes, here are the changes and output. If I type the name in different orders it still allows a username thats already been written in the file to be appended.

###################################
########## Register File ##########
###################################

# Open usrdata for read to check for username, pw match########
usrinfile = open("usrdata", 'r')

usrdatalist = [] # Create a list to check

for line in usrinfile:
    un, pw = (line.split(','))
    usrdatalist.append([un, pw])
# Close file
usrinfile.close()
###############################################################

# Get information from user
username = input("Enter a username: ")
#password = input("Enter a password: ")

# Create list of takes names
badnames = []
for n in usrdatalist:
    badnames.append(n[0])

for n in badnames:
    while n == username:
        username = input("Name taken, enter new name: ")
    print(n)
Output:
/usr/bin/python3.5 /root/PythonProjects/video_game/registry.py Enter a username: josh Name taken, enter new name: ryan josh Name taken, enter new name: loki ryan Name taken, enter new name: josh loki Process finished with exit code 0

with this loop, I've noticed if I type a name toward the end of the list, get the notice that the name is taken and to enter a new name, typing a name toward the beginning or before the name typed previously then the program continues... basically ignoring the check in the while loop.

badnames = []
for n in usrdatalist:
    badnames.append(n[0])
    while (n[0] == username):
        username = input("Name taken, enter new name: ")
Output:
/usr/bin/python3.5 /root/PythonProjects/video_game/registry.py Enter a username: loki Enter a password: me Name taken, enter new name: josh Process finished with exit code 0
in my list the usernames are as follows:
josh
ryan
loki


RE: trouble writing to file after while loop - Larz60+ - Jan-04-2017

Hello,

It's better to use 'with' for file io as it is more compact, and you don't have to close the file, it's done automatically.
Try:
###################################
########## Register File ##########
###################################
usrdatalist = []

# Open usrdata for read to check for username, pw match########
with open("usrdata", 'r') as f:
    for line in f.readlines():
        un, pw = (line.split(','))
        usrdatalist.append([un, pw])

###############################################################
# Get information from user


username = input("Enter a username: ")
for n, item in enumerate(usrdatalist):
    un = item[0]
    while un == username:
        username = input("Name taken, enter new name: ")
    
    usedatalist[n] = username
    print(username)

    # enter new password here
    # password = input("Enter a password: ")
    # May want to have password entered twice and compare for equality
    # Encrypt password before saving

    # with open("usrdata", 'w') as f:
    #     for item in userdatalist:
    #         f.write('{} {}\n'.format(item))
I cant test this because I don't have the data file

You also need to save this back to the file
I'd also install passlib so that you can hide input and encrypt the password

If you want to use passlib:
pip install passlib



RE: trouble writing to file after while loop - Low_Ki_ - Jan-04-2017

Thank you for the response, I'm testing it now. Sorry I just picked up programming a week ago, I know my code probably looks newbie as heck and sloppy as could be lol.

Even using your code I get the output that if a name in my file is entered it prompts for a new name unless you enter a name that is before the name entered on the list.
I test it by using a simple text file with a list of (names,password).
Ex:
josh,josh
ryan,ryan
loki,loki

Output:
/usr/bin/python3.5 /root/PythonProjects/video_game/registry.py Enter a username: josh Enter a password: me Name taken, enter new name: ryan Name taken, enter new name: loki Name taken, enter new name: josh Process finished with exit code 0

Okay did some fixing. It's still appending multiple times. With the 'w' is wasn't writing at all, changed 'w' to 'a' and it appends multiple time.

###################################
########## Register File ##########
###################################
usrdatalist = []

# Open usrdata for read to check for username, pw match########
with open("usrdata", 'r') as f:
   for line in f.readlines():
       un, pw = (line.split(','))
       usrdatalist.append([un, pw])

###############################################################
# Get information from user


username = input("Enter a username: ")
for n, item in enumerate(usrdatalist):
   un = item[0]
   while un == username:
       username = input("Name taken, enter new name: ")

   usrdatalist[n] = username
   print(username)

# enter new password here
password = input("Enter a password: ")
   # May want to have password entered twice and compare for equality
   # Encrypt password before saving

with open("usrdata", 'a') as f:
   for item in usrdatalist:
       f.write(username + "," + password +'\n'.format(it
Output:
/usr/bin/python3.5 /root/PythonProjects/video_game/registryTest.py Enter a username: josh Name taken, enter new name: ryan ryan Name taken, enter new name: loki loki Name taken, enter new name: josh josh josh josh josh Enter a password: me Process finished with exit code 0
[Image: Screenshot%20from%202017-01-04%2010-32-2...zethts.png]

Sorry, this is the code. Ignore above.

###################################
########## Register File ##########
###################################
usrdatalist = []

# Open usrdata for read to check for username, pw match########
with open("usrdata", 'r') as f:
    for line in f.readlines():
        un, pw = (line.split(','))
        usrdatalist.append([un, pw])

###############################################################
# Get information from user


username = input("Enter a username: ")
for n, item in enumerate(usrdatalist):
    un = item[0]
    while un == username:
        username = input("Name taken, enter new name: ")

    usrdatalist[n] = username
    print(username)

# enter new password here
password = input("Enter a password: ")
    # May want to have password entered twice and compare for equality
    # Encrypt password before saving

with open("usrdata", 'a') as f:
    for item in usrdatalist:
        f.write(username + "," + password +'\n'.format(item))



RE: trouble writing to file after while loop - Larz60+ - Jan-04-2017

Ok,

On the file dump you show above (other than the duplication)
is the layout as you wish it to be?

Output:
josh,mi ryan,th ...
Need to know so I can test here.

Also when pasting code, you (usually) need ctrl-shift-V
so that you don't show all the markdown.


RE: trouble writing to file after while loop - Larz60+ - Jan-04-2017

I rewrote as a class, there were just too many things wronf with the other code
Here's a complete class to get you started.
import json
import os


class NewPassword:
    def __init__(self, filename=None):
        self.usrdatalist = None
        self.filename = filename
        if self.filename is not None:
            if not os.path.exists(filename):
                self.init_file()
            else:
                with open(self.filename, 'r') as f:
                    j = f.read()
                    self.usrdatalist = json.loads(j)

    def init_file(self):
        data = [('user', 'password')]
        with open(self.filename, "w") as f:
            j = json.dumps(data)
            f.write(j)

    def rewrite_file(self):
        with open(self.filename, "w") as f:
            j = json.dumps(self.usrdatalist)
            f.write(j)

    def new_user(self):
        while True:
            username = input("Enter a username: ")
            if username in self.usrdatalist:
                username = input("Name taken, enter new name: ")
                continue
            break
        password = None
        while not password:
            password = input('Enter password: ')
            if len(password) < 12:
                print('Password must be at least 12 characters long')
                password = None
                continue
        self.usrdatalist.append((username, password))
        self.rewrite_file()

def main():
    cp = NewPassword(filename="usrdata.json")
    cp.new_user()

if __name__ == '__main__':
    main()
The password needs to be encoded, double checked, and blanked out while entering
without that, this code is of little use.
If using a gui, you can use getpass (builtin)


RE: trouble writing to file after while loop - Low_Ki_ - Jan-05-2017

Yes the layout as is I wish it to be, just a simple appended list of usernames and passwords. Will encrypt passwords, I'm trying to solve one issue at a time ;). I greatly appreciate the help. I ran the code you've just given me and the output I get is this:

Output:
Enter a username: josh Traceback (most recent call last):   File "/root/PythonProjects/video_game/registryTest.py", line 52, in <module>     main()   File "/root/PythonProjects/video_game/registryTest.py", line 48, in main     cp.new_user()   File "/root/PythonProjects/video_game/registryTest.py", line 31, in new_user     if username in self.usrdatalist: TypeError: argument of type 'NoneType' is not iterable Process finished with exit code 1
import json
import os


class NewPassword:
    def __init__(self, filename=None):
        self.usrdatalist = None
        self.filename = filename
        if self.filename is not None:
            if not os.path.exists(filename):
                self.init_file()
            else:
                with open(self.filename, 'r') as f:
                    j = f.read()
                    self.usrdatalist = json.loads(j)

    def init_file(self):
        data = [('user', 'password')]
        with open(self.filename, "w") as f:
            j = json.dumps(data)
            f.write(j)

    def rewrite_file(self):
        with open(self.filename, "w") as f:
            j = json.dumps(self.usrdatalist)
            f.write(j)

    def new_user(self):
        while True:
            username = input("Enter a username: ")
            if username in self.usrdatalist:
                username = input("Name taken, enter new name: ")
                continue
            break
        password = None
        while not password:
            password = input('Enter password: ')
            if len(password) < 12:
                print('Password must be at least 12 characters long')
                password = None
                continue
        self.usrdatalist.append((username, password))
        self.rewrite_file()


def main():
    cp = NewPassword(filename="usrdata.json")
    cp.new_user()


if __name__ == '__main__':
    main()
[Image: Screenshot%20from%202017-01-04%2019-45-0...hypnre.png]

Gah... I feel like a registry form shouldn't be this difficult. It's my first year of study in computer science in Texas A&M. Actually my first semester as well. My professor says that I have lots of potential because of my self-motivation to study and create programs on my own... like novice calculators and simple design with loops and lists. LMAO. I am trying though and it seems this registration form has been a test on my novice level skills because the class code you wrote... I understand very little of it. HAHA

I would like to thank you for your time as I know time is irreplaceable and it does mean a lot to me.


RE: trouble writing to file after while loop - Larz60+ - Jan-05-2017

You need to delete (or if this is part of a working system, convert) the old file.
I use json which makes saving and loading simple
If you remove the old file, a new one will be started. From that point forward,
it will work ok. I also suggest that you add some sort of backup mechanism.

One more time I emphasize that you at least encrypt that passwords before saving


RE: trouble writing to file after while loop - Low_Ki_ - Jan-05-2017

Awesome it worked just fine. Thanks for your help :D.


RE: trouble writing to file after while loop - Skaperen - Jan-05-2017

(Jan-05-2017, 03:20 AM)Larz60+ Wrote: One more time I emphasize that you at least encrypt that passwords before saving

even better is to use one-way encryption.