0

I'm teaching myself programming and today's challenge is to write a program that can align text left,right or centre. My major problem is that once I open a file, I'm not sure how to write to specific lines. Is there an easy way to do this? This is what I have. I'm thinking I will need to somehow figure the bytes in the line so that I can f.seek to the end of the line. I feel like python would already have this type of functionality somewhere but I couldn't find it searching online. Any suggestions?

def align():
    name= input('what is the name of your txt file?: ')
    try:
        f=open(name + '.txt','r+')
        lines =f.readlines()
        just = input('left, right, or centre?: ')
        for i in range[,lines]:
            j = lines[i].strip('\n')
            if just == 'right':
                f.seek() #I want it to seek each line but can't figure out what variable might go here...
                f.write('{:>30}'.format(line.strip()))
            elif just == 'left':
                f.seek() #I want it to seek each line but can't figure out what variable might go here...
                f.write('{:<30}'.format(line.strip()))
                f.seek() #I want it to seek each line but can't figure out what variable might go here...
            elif just == 'centre' or just == 'center':
                f.write('{:^30}'.format(line.strip()))
        else:
            print("You didn't choose a justification!")
        f.close()
jdi
  • 90,542
  • 19
  • 167
  • 203
Terence Chow
  • 10,755
  • 24
  • 78
  • 141
  • 5
    Normally what you would do is read the lines into memory one by one, write them out to a new file in the same order, and then replace the old file with the new one. – Amber Jun 23 '12 at 18:06
  • possible duplication of http://stackoverflow.com/questions/4719438/editing-specific-line-in-text-file-in-python – xvatar Jun 23 '12 at 18:09
  • `seek()` takes an int that says how many bytes to seek to. `seek(0)` resets the position to start – jdi Jun 23 '12 at 18:16
  • @xvatar so odd I did a search for that...not sure why I couldn't find it thanks Amber & jdi thanks for teaching me the correct /clean process – Terence Chow Jun 24 '12 at 02:11

2 Answers2

5

There's a lot of duplication in your code, it can / should be eliminated, for example, the following handles all three possibilities:

for line in infile:
    print '{:{}{}}'.format(line.strip(), align, width)

where width is a number, and align - one of <, > or ^.

As to the "seek" problem, as others already suggested, it's better to redirect the output in another file instead of rewriting the input file "in place":

with open("in.txt", 'r') as infile, open("out.txt", 'w') as outfile: 
   for line in infile:
        outfile.write('{:{}{}}\n'.format(line.strip(), align, width))

A with statement like with open(...) as var: do stuff is roughly the same as the following:

  var = open(...)
  do stuff
  close(var)

but far less error-prone.

georg
  • 211,518
  • 52
  • 313
  • 390
  • 1
    Nice concise answer. Maybe you should add a quick sentence about the `with` context, since I am sure that is new to the OP – jdi Jun 23 '12 at 18:24
  • @jdl: I'm rather concerned about `{:{}{}}` which might be quite confusing for a beginner. – georg Jun 23 '12 at 18:33
  • Why? The OP are already using the `format` method in the example. Seems like they are already investigating it. – jdi Jun 23 '12 at 18:41
  • This looks great. Thanks a lot for teaching me a cleaner process. – Terence Chow Jun 24 '12 at 02:10
1

No, you can't seek to a given line directly (unless all lines are exactly of the same length in which case you might be able to computer the correct offsets).

The two approaches you have is to read all of the file into memory at once using readlines(), or do do it line-by-line and keep a count, like this:

with open('data.txt') as inf:
     for count, line in enumerate(inf, 1):
         if count == 10:
             print 'found "{}" at line 10.'.format(line)

enumerate() will keep a count for you automatically starting with 1

Note that opening the file using with will make sure the file is properly auotmatically closed when you are done with it, or an exception occurs.

The alternate approache with readlines() will read the whole file into a list and you can access a given line via the index. This may be a problem with memory if the file is huge.

Once you have the line(s) you are interested in, you can format and write it out to a different file as needed.

Levon
  • 138,105
  • 33
  • 200
  • 191