Reputation: 11153
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()
Upvotes: 0
Views: 186
Reputation: 143047
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.
Upvotes: 1
Reputation: 214959
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.
Upvotes: 5