0

I'm currently creating a database API in order to get a better grasp of how APIs work. Currently fixing the errors and whatnot, when I tried the delete function (Option 3), it gives me an error and tells me that the split function is returning one value rather than two.

My guess is that it's either reading the lines incorrectly, or through reading the text file, it doesn't register the tab ('\t') but rather as a space (' ') at times.

I'm doing this through VS Code, not sure if that's a contributing factor at all with the indents and stuff. But I've got it at 4 spaces = tab like the Python IDLE does normally.

Here's the code:

import time

def add(filename):
    print('Name?')
    key = input()
    print('Phone number?')
    value = input()
    f = open(filename, "a")
    f.write(key + "\t" + value + "\n")
    f.close()

def find(filename, key):
    f = open(filename, "r")
    for line in f:
        #first stores the current key in variable
        (currentKey, currentValue) = line.split('\t', 1)
        if currentKey == key:
            return currentValue[:-1]
    f.close()

def delete(filename, key):
    f = open(filename, "r")
    f1 = open('temporary.txt', "w")
    for (line) in f:
        #Error occurs here
        (currentKey, currentValue) = line.split('\t', 1)
        if currentKey != key:
            f1.write(line)
    f.close()
    f1.close()
    import os
    os.replace('temporary.txt', filename)
    

def update(filename, key, value):
    resultfile = "temporary.txt"
    f = open(filename, "r")
    f1 = open(resultfile, "w")
    for line in filename:
        (currentKey, currentValue) = line.split('\t', 1)
        if currentKey != key:
            f1.write(line)
        else:
            f1.write(currentKey + '\t' + value + '\n')
    f.close()
    f1.close()
    import os
    os.replace(resultfile, filename)

filename = 'telephone.txt'

#Current Menu Interface
def menu():
    print("Welcome to the telephone directory")
    print("Your options are:")
    print()
    print("1) Adding")
    print("2) Finding")
    print("3) Deleting")
    print("4) Updating")
    print("5) Quitting")
    choice = input()
    return choice

#actual decision code
def decision(choice):
    loop = 1
    while loop == 1:
        if choice == '1':
            add(filename)
            choice = menu()
        elif choice == '2':
            print("What is the name of the person you are looking for?")
            key = input()
            value = find(filename, key)
            print(key + "'s phone number is: " + value)
            choice = menu()
        elif choice == '3':
            print("What is the name of the person you are looking to delete from the directory?")
            key = input()
            delete(filename, key)
            choice = menu()
        elif choice == '4':
            print("What is the name of the person?")
            key = input()
            print("What is the telephone number you want to replace it with?")
            value = input()
            update(filename, key, value)
            choice = menu()
        elif choice == '5':
            print("Thank you for using the program! Your file contents are stored in a file called 'telephone.txt'.")
            time.sleep(1)
            loop = 0
        else:
            print("Please enter a value from 1 to 5. No spaces at all.")
            choice = menu()

choice = menu()
decision(choice)
7
  • 1
    can you print the value of line before using split Commented Feb 8, 2021 at 18:35
  • Upvote and mark it as answer if the answer below solves your problem Commented Feb 8, 2021 at 18:39
  • Yeah, I just commented on that answer. Unfortunately, I wished that was the only mistake I committed but it seems to not be the case. As for printing the value of line, the code is able to find the correct line accordingly. It prints out the key (a name in this case), a significant \t in between and a value (a number in this case). Commented Feb 8, 2021 at 18:43
  • if your separator could be tab or space, you could just use line.split(None,1) Commented Feb 8, 2021 at 22:31
  • Could you elaborate on the None value? In my file I've always set the '/t' value as the separator. But it seems like a space value in the txt file itself because of the way tabbing works. Commented Feb 8, 2021 at 22:35

1 Answer 1

2

You're iterating over the string filename, not the file handle:

def delete(filename, key):
    f = open(filename, "r")
    f1 = open('temporary.txt', "w")
    for (line) in filename: # here
        ...

Which means that you are getting each character in filename. So if filename is 'hello.txt', you'd get:

h
e
l
l
o
.
t
x
t

You should be doing

f = open(filename)
for line in f:
    # rest of loop

Or, rather:

with open(filename) as f:
    for line in f:
        # rest of loop

Last, if your lines do not contain a tab, str.split('\t') will return a single-element list, so you could do:

try:
    a, b = line.split('\t', 1)
except ValueError:
    print('No tab in line')
    continue # skip the line

Alternatively, you could raise if you want the program to stop

try:
    a, b = line.split('\t', 1)
except ValueError:
    print('No tab in line')
    raise # stop the program

Last, the best way to handle either tabs or spaces would be the way that @RufusVS suggested:

try:
    a, b = line.split(None, 1)
except ValueError:
   # either raise or continue
   print('Line doesn't contain a whitespace separator')
   continue

Where str.split gets passed None because the function is expecting a separator argument, and omitting it will raise an error:

x = 'abc def'

x.split(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str or None, not int

x.split(None, 1)
['abc', 'def']
Sign up to request clarification or add additional context in comments.

2 Comments

Good point, I just changed my code so it reflects that, but I still get the same error nonetheless.
As it turns out, I must've tampered the .txt file directly because once I deleted my previous entries it worked perfectly fine. But thank you for writing out an elaborate explanation of possible errors I have made along the way! You have earned my upvote and check mark.

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.