Auto complete for user input

I began writin down my login data in a text file, now it got very big so i wrote a small program where I can type in a website and get the login data. It works when I write the website exactly like in the text file but I want to implement a system that gives me the closest match when I mess the name up.

def search_and_print(website):

passwort_text = open("D:/Programme/Python/Projects/test", "r+")
points_text = open("D:/Programme/Python/Projects/Point record", "r+")
letter_list = []
line_list = []
index = 0
for line in passwort_text.readlines():
    counter = 0
    if website.upper() in line.upper():
        check = True
    try:
        if line != "\n" and check:
            print("\n" + line, end="")
        elif line == "\n":
            check = False
    except UnboundLocalError:
        pass
       #    the code above looks for in all lines for the exact word I gave it and gives me 
       #     the next lines until it hits an empty line
    else:
        for letter in website:
            letter_list.append(letter)
        for letter_line in line:
            line_list.append(letter_line)
        if letter_list[index] == line_list[index]:
            counter += 1
            index += 1
            print("test")
        else:
            print(line_list[index])
            #print(letter_list[index])
            index += 1
  # my idea here was to write the current line in a list as separate letters, so I can compare this list 
  # with a list where I did the same for the input the programm gets

points_text.close()
passwort_text.close()

My question here would be if this is a good aproach or not and if not how I could do it better.
Thanks in advance.

this is the content of the test file I use:

Website: Netflix
E-Mail: test@outlook.de
Username: test
Passwort: idontkonw

Website: Paypal
E-Mail: test
Username: test
Passwort: 1342352352

1 Like

There is difflib.get_close_matches in the standard library, which sounds like what you’re after.

You need to feed it a list of possible matches (websites in your case), but it looks like it should be possible to parse that from your file.

1 Like

I’ll try that thank you

1 Like

Ok I implemented it and it works just fine as long as I type in a wrong website, however when I give it a correct website it prints out the same login data twice.

def search_and_print(website):
passwort_text = open("D:/Programme/Python/Projects/test", "r+")
for line in passwort_text.readlines():

    if website.upper() in line.upper():
        check = True
    try:
        if line != "\n" and check:
            print("\n" + line, end="")
        elif line == "\n":
            check = False
    except UnboundLocalError:
        pass
    else:
        if not difflib.get_close_matches(website, [line], 1, 0.4):
            pass
        else:
            second_check = True
    try:
        if line != "\n" and second_check:
            print("\n" + line, end="")
        elif line == "\n":
            second_check = False
    except UnboundLocalError:
        pass

passwort_text.close()

What I want when I type in Netflix:

Website: Netflix

E-Mail: test@outlook.de

Username: test

Passwort: idontkonw

What I get:

Website: Netflix

Website: Netflix

E-Mail: test@outlook.de

E-Mail: test@outlook.de

Username: test

Username: test

Passwort: idontkonw

Passwort: idontkonw
1 Like

You can add a break statement after the first print statement. That will cause the for loop to exit after printing the matching line.

Also, I’d consider it unpythonic to use UnboundLocalError like that. It would be better to initialise check with a default value of False like this:

def search_and_print(website):
	passwort_text = open("D:/Programme/Python/Projects/test", "r+")
	
	check = False  # < set default value of 'check'
	
	for line in passwort_text.readlines():

		if website.upper() in line.upper():
			check = True
		
		if line != "\n" and check:
			print("\n" + line, end="")
			break  # < add break here
		elif line == "\n":
			check = False
				
		else:
			if not difflib.get_close_matches(website, [line], 1, 0.4):
				pass
			else:
				check = True
		
		if line != "\n" and check:
			print("\n" + line, end="")
		elif line == "\n":
			check = False
	

	passwort_text.close()

I think that should work the same.

1 Like

Yes it works perfectly thanks for your help :slight_smile:

2 Likes