Reputation: 1196
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)
Upvotes: 0
Views: 254
Reputation: 13106
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']
Upvotes: 2