Python Forum
trouble writing to file after while loop
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
trouble writing to file after while loop
#1
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()
Reply
#2
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
Reply
#3
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
Reply
#4
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))
Reply
#5
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.
Reply
#6
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)
Reply
#7
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.
Reply
#8
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
Reply
#9
Awesome it worked just fine. Thanks for your help :D.
Reply
#10
(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.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Writing string to file results in one character per line RB76SFJPsJJDu3bMnwYM 4 1,309 Sep-27-2022, 01:38 PM
Last Post: buran
  Writing to json file ebolisa 1 970 Jul-17-2022, 04:51 PM
Last Post: deanhystad
  Writing to External File DaveG 9 2,411 Mar-30-2022, 06:25 AM
Last Post: bowlofred
Question Having trouble writing an Enum with a custom __new__ method stevendaprano 3 4,010 Feb-13-2022, 06:37 AM
Last Post: deanhystad
  Writing to file ends incorrectly project_science 4 2,642 Jan-06-2021, 06:39 PM
Last Post: bowlofred
  Writing unit test results into a text file ateestructural 3 4,654 Nov-15-2020, 05:41 PM
Last Post: ateestructural
  Writing to file in a specific folder evapa8f 5 3,337 Nov-13-2020, 10:10 PM
Last Post: deanhystad
  Trouble with reading csv file and putting it into a file Milfredo 3 2,218 Sep-04-2020, 05:30 AM
Last Post: Milfredo
  Failure in writing binary text to file Gigux 7 3,718 Jul-04-2020, 08:41 AM
Last Post: Gigux
  writing data to a csv-file apollo 1 2,329 Jul-03-2020, 02:28 PM
Last Post: DeaD_EyE

Forum Jump:

User Panel Messages

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