1

I am trying to get user inputs to create a file where users can store website, username, and password in table format whenever users hit a button. I made the function below, and it looks okay to me. However, when a user enters the second and third entries, the data frame structure is broken. Any idea why it happens? You may see the print result each time adding a row to my data.

Code:

from tkinter import *
import pandas as pd
import os

def save_password():
    website_name = input("Website: ")
    username = input("Username: ")
    password = input("Password: ")
    # password_details = f"website: {website_name};username: {username};password: {password}"
    input_entries_dict = {"Website": [website_name],
                          "Username/Email": [username],
                          "Password": [password]}
    input_entries_df = pd.DataFrame(input_entries_dict)
    if not os.path.isfile("MyPassword_test.txt"):
        input_entries_df.to_csv("MyPassword_test.txt", index=False)
        print(input_entries_df)
    else:
        data = pd.read_csv("MyPassword_test.txt")
        data = data._append(input_entries_df, ignore_index=True, sort=True)
        print(data)
        data.to_csv("MyPassword_test.txt", sep=";", index=False)

save_password()

Outputs for each time:

First entry: ALL FINE
  Website Username/Email Password
0  d32d23        f7324f2  f3223f2

Second Entry: Column names are shifted
       Password Username/Email  Website
0       f3223f2        f7324f2   d32d23
1  ddwefddsfds5       32fwefw5  48sfd4s

Third Entry:Colum of "Password;Username/Email;Website" created!
  Password Password;Username/Email;Website Username/Email    Website
0      NaN          f3223f2;f7324f2;d32d23            NaN        NaN
1      NaN   ddwefddsfds5;32fwefw5;48sfd4s            NaN        NaN
2   154152                             NaN      f32f23f23  2f23f2332
1
  • don't use private methods Commented Apr 2 at 14:34

2 Answers 2

2

The confusion is caused by writing the .CSV with a ; separator but ignoring this on reading. Use:

    else:
        data = pd.read_csv("MyPassword_test.txt")
        data = pd.concat([data, input_entries_df], ignore_index=True)
        print(data)
        data.to_csv("MyPassword_test.txt", index=False)
Sign up to request clarification or add additional context in comments.

Comments

1

Your core issue here is that in the case of an existing file, you rewrite the file with a non-default separator sep=";" and thus:

  • the first entry works (using commas)
  • the second entry works reading commas but writing semi-colons
  • the third (and subsequent) entry fails reading expecting commas but finding none.

The fix is to use a standard separator. Either accept the default everywhere or override it everywhere.

In any case, you should stop using ._append() and switch to pandas.concat()

I would likely use the csv package here rather than pandas but if you are keen on pandas, I might suggest.

import pandas
import os

def save_password(website_name, username, password):
    password_file = "MyPassword_test.txt"   # I might think about passing this in as a fourth argument
    new_record= {
        "Website": [website_name],
        "Username/Email": [username],
        "Password": [password]
    }

    ## --------------
    ## If the file does not exist, create it with the required columns
    ## Note: use columns=list(new_record.keys()) if you want to be explicit
    ## --------------
    if not os.path.isfile(password_file):
        pandas \
            .DataFrame(columns=new_record) \
            .to_csv(password_file, index=False)
    ## --------------

    ## --------------
    ## Since we now know the file exists, we can always append the new record
    ## --------------
    pandas \
        .concat([
            pandas.read_csv(password_file),
            pandas.DataFrame(new_record)
        ]) \
        .to_csv(password_file, index=False)
    ## --------------

## --------------
## I try to avoid asking for input in methods that could accept arguments
## --------------
website_name = input("Website: ")
username = input("Username: ")
password = input("Password: ")
save_password(website_name, username, password)
## --------------

1 Comment

Appreciate it..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.