0

I have a username-password login system and would like to add a delete user function. The usernames are stored on the even lines of a text file (inc zero) and the passwords on odd numbered lines. Is there a way of adding only the even numbered lines to a listbox to be selected via curselection to be deleted as showing the passwords would be against the point. I currently have all of the contents of the text file showing in the listbox however would like only the usernames to be shown. To delete the lines I have copied the contents of the listbox to a new text file after removing the chosen line from the listbox. Would there also be a way to delete the corresponding password after the username to be deleted has been selected ?

def DelUser():

    global rootDU
    global listbox

    rootDU = Tk()
    rootDU.title('Delete user')

    users = open(creds, 'r')
    mylist = users.readlines()
    users.close()

    listbox = Listbox(rootDU, width=50, height=6)
    listbox.grid(row=0, column=0)
    yscroll = Scrollbar(command=listbox.yview, orient=VERTICAL)
    yscroll.grid(row=0, column=1, sticky=N + S)
    listbox.configure(yscrollcommand=yscroll.set)

    enter1 = Label(rootDU, text='Click on the user to delete', width=50)
    enter1.grid(row=1, column=0)

    for item in mylist:
        listbox.insert(END, item)

    delButton = Button(rootDU, text='Delete', command=RemoveUser)
    delButton.grid(columnspan=2, sticky=W)
    delButton.grid(row=2, column=0)

def RemoveUser():

    global listbox

    try:
        index = listbox.curselection()[0]
        listbox.delete(index)
        os.remove(creds)
        newfile = 'tempfile.txt'
        with open(newfile, 'w') as f:
            f.write(''.join(listbox.get(0, END)))
            f.close()

    except IndexError:
        pass
alee23
  • 45
  • 1
  • 8
  • This is too many questions in one. If the actual problem is to read every even line from a file, reduce the question accordingly. – timgeb Apr 30 '17 at 10:23

1 Answers1

1

Just add only every second line to your listbox:

for item in mylist[::2]:
    listbox.insert(END, item)

The ::2 slice picks every second line, starting at line 0. See Explain Python's slice notation for further details.

You then still have to re-read the file to find the corresponding password however, since you don't store that information separately. You really want to store a mapping from usernames to passwords (separately, as information you share between DelUser and RemoveUser) so you can easily re-write your user file with the remaining users and passwords.

You could also consider using a different format for your file; writing usernames and passwords on the same line, but putting a delimiter character between them, would make it easier to process the data.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • how would I access the line after that of the one being selected as this will be the one containing the password which would need to be deleted as well ? – alee23 Apr 30 '17 at 14:25
  • @alee23: exactly; you need to read in the file again afterwards, find the line with the username and then also the next line. It's easier if you kept everything on one line (`'username:password\n'`). – Martijn Pieters Apr 30 '17 at 15:00
  • how would I do this without having the lines in this format as I have used this for multiple parts of my code and would need this idea of deleting corresponding lines in another part of my code ? – alee23 Apr 30 '17 at 17:55
  • You could use any number of techniques. Read the file, then write out all lines except for the one that matches the deleted username, then skip writing the next line too (use a flag), for example. Or reach the whole file into a dictionary (pair up usernames and passwords), delete the username from that, then write out all pairs again, etc. – Martijn Pieters Apr 30 '17 at 18:30
  • As you suggested, if I were to keep everything on one line ( `'username:password\n'`) how would I only display the usernames in the listbox ? – alee23 May 01 '17 at 09:59
  • @alee23: partition each line: `username = line.partition(':')[0]`. – Martijn Pieters May 01 '17 at 12:57
  • how would this look when inserting each line into the listbox ? – alee23 May 01 '17 at 20:50
  • You do have to do a little bit of thinking yourself. :-) You already have a `for` loop over the lines, where you insert each `item`. Try to think through what that does, and how my previous comment could apply there. – Martijn Pieters May 01 '17 at 21:30
  • I have the partition working but how would I now delete the line from the text file as before I removed the line from the listbox and then copied the contents of the listbox to the text file, however that would only copy the usernames now as they are the only items in the listbox – alee23 May 02 '17 at 08:25
  • @alee23: read the file again, only keep the lines that don't start with the removed username, write the file again. However, you may want to store the usernames and passwords elsewhere in your program so you don't have to keep reading the file each time. Your listbox is not the only place you can store that information. – Martijn Pieters May 02 '17 at 08:26
  • by changing the format of how I store the usernames and passwords, this has changed how a different part of my code works. It was a CheckLogin function that checked if the input was found in the text file. How would I do this with this new format of username:password ? – alee23 May 02 '17 at 08:41
  • Sorry, I'm not going to solve every problem for you in comments. If you have new issues, you can post a new question. However, I'm sure that if you can get splitting a line to work, you can work out how to test the username and password too. – Martijn Pieters May 02 '17 at 08:45