0

I am having an issue with a timetracker program, where I am trying to identify a line in a file by iterating over it and then writing the lines UNLESS there is anything with the variable "delete" in it, for some reason its going through the file and saying it is deleted, but the loop doesn't delete any lines.

date = input(" What is today's date? month-day-year format please. (E.G. 01-14-2003) ")
if os.path.exists(date):
    today = open(date, "r")
    print(today.read())

    delete = input(" Which appointment would you like to delete? (Please type the time E.G. 7:00) ")

    #Open the file, save the read to a variable, iterate over the file, check to see if the time is what user entered, if it is not then write it to the line, close the file.

    fileEdit = open(date, "r+")
    for line in today.readline():
        print(line)
        if delete not in line:
            fileEdit.write(line)
    print(fileEdit.read())
    today.close()
    fileEdit.close()
    print ("Appointment deleted, goodbye")
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dirk Dunn
  • 11
  • 2
  • Is this `if delete not in line:` ever `False`? Try this by putting in: `else: print 'Deleting line.'`. Also open files like this: `with open('filename.txt', 'w') as f:`. – Aleksander Lidtke Nov 06 '13 at 21:05
  • [How do I write to the middle of a text file while reading its contents?](http://stackoverflow.com/a/16563027/4279) – jfs Nov 06 '13 at 21:15

4 Answers4

2

This is reading to the end of the file

print(today.read())

When you start iterating here, you're already at the end

for line in today.readline():

so the for loop will never be entered. You need to reopen the file or seek back to the beginning.

Another problem is that you are iterating over the first line. You probably meant

for line in today:

Regardless, it's generally not a great idea to write to the same file you are reading (eg. consider the mess the file would be in if the computer gets reset partway through)

Better to write a temporary file and replace.

If the files are very small, you could read the file into a list in memory and then rewrite the file out again.

A better idea, before you go too far is to use a database such as the sqlite module (which is builtin to Python)

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

today.readline() returns a single line. The for-loop iterates over characters in that line. And as @gnibbler pointed out the today file is at the end of file at the time today.readline() is called (so it returns an emtpy string).

In general, to delete something in the middle of a file you need to replace the file completely. fileinput module can help:

import fileinput

for line in fileinput.input([date], inplace=1):
    if delete not in line:
       print line, # stdout is redirected to the `date` file

Here's almost the same but without fileinput:

import os
from tempfile import NamedTemporaryFile

filename = date
dirpath = os.path.dirname(filename)
with open(filename) as file, NamedTemporaryFile("w", dir=dirpath) as outfile:
    for line in file:
        if delete not in line:
           print >>outfile, line, # copy old content
    outfile.delete = False # don't delete outfile
os.remove(filename) # rename() doesn't overwrite on Windows
os.rename(outfile.name, filename) # or just `os.replace` in Python 3.3+
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
1

The problem comes from reading and writing the same file. Here is some explanation on that.

Good reference (Beginner Python: Reading and writing to the same file)

So when in r+ mode, both reading and writing to the file move the file pointer forward.

So let's look at your example. First you do a readline. This moves the file pointer to the next line. You check if the line you just read is valid or not and write it if it is.

The problem is that you just overwrote the next line, not the previous one! So your code is really messing up your data.

Bascially it's really hard (and inefficient if the file is large) to do want you want to do right. You can't arbitrarily delete bytes out of the middle of a file. For each line you wanted to delete, you'd have to write the rest of the data over it then truncate the file at the end to delete the freed space.

You should take the advice of the other answers and either output to another file or stdout.

Community
  • 1
  • 1
korylprince
  • 2,969
  • 1
  • 18
  • 27
0

Well you can do the following also:

with open("input.txt",'r') as infile, open("output.txt",'w') as outfile: 
    # code here

    outfile.write(line)

In your file loop, you can do something like:

if delete:
   continue

to skip the line that you don't want to write to the output file.