Chad D
Chad D

Reputation: 559

characters limit per line in outputfile

So my goal here is trying to limit characters in the outputfile to 6 characters per line. Here is what i have so far but this doesn't work: One of the error that i got is can't concatenate str and int

def charLimit(outputfile):

        limit =6
        char = 0
        with open(outputFile,'r+') as file:
           for char in char.len():
               if char != 6 :
                  char = file.read(char)
                  char += 1
              else:
                  file.write('\n')
                  char = 0

Upvotes: 1

Views: 5322

Answers (4)

Joel Cornett
Joel Cornett

Reputation: 24788

You can't just read/write into the same file simultaneously because you're inserting newlines every 6 characters. Those newlines will overwrite the next character in the file. Say the contents of the file are the following:

123456789

If you simply write a newline to the file after every 6th line, your file will be the following:

123456
89

Notice how the newline overwrote "7".

If your file is relatively small (a couple megabytes maybe), you can avoid creating a tempfile and just read the entire file into memory, set the buffer position back to 0, and overwrite it, like so:

with open(filename, 'r+') as f:
    raw = f.read()
    f.seek(0) #sets the buffer position back to the beginning of the file
    for i in xrange(0, len(raw), limit):
        line = raw[i:i+limit].rstrip('\n').replace('\n', ' ')
        f.write(line + '\n') 

If your file is very large, however, it makes sense not to load the entire data into memory, and instead write to a temp file, and copy afterwards:

with open(filename, 'r') as infile, open('tmp.txt', 'w') as outfile:
    line = 
    while True:
        line = infile.read(limit)

        #if there is no more text to read from file, exit the loop
        if not line:
            break 

        outfile.write(line.rstrip('\n').replace('\n', ' ') + '\n')

import shutil

shutil.copyfile('tmp.txt', filename)

Upvotes: 0

jfs
jfs

Reputation: 414265

To get exactly 6 characters per line (not including newline itself) disregarding word boundaries:

import fileinput
from itertools import chain, izip_longest

limit = 6
lines = (line.rstrip('\n') for line in fileinput.input([outputFile], inplace=1))
chars = chain.from_iterable(lines) # all characters
for chunk in izip_longest(*[chars]*limit, fillvalue=''): # grouper recipe*
    print(''.join(chunk)) # write to outputFile
fileinput.close() # close outputFile, delete backup

*grouper recipe

The code creates a backup file and redirects stdout to outputFile, then it reads (lazily) the file line by line stripping newline character and chaining the lines into a single stream of characters, then it writes limit characters per line using the grouper recipe, finally it closes the file and deletes the backup.

This code is not for a beginner (just an exercise).

Upvotes: 0

Your error message ("cannot concatenate string and int") comes from the fact that the read() method returns a string. So when in the next line you add 1 to char, you are trying to combine a string with an int using the + operator, which is not possible.

If you would like to add the 1 numerically, use the built-in int() method, e.g.

char = int(char) + 1

If you would like to add the 1 as a string, use

char += '1'

Upvotes: 0

jfs
jfs

Reputation: 414265

You could use textwrap module:

import textwrap

with open(outputFile) as file:
     text = file.read()

with open(outputFile, 'w') as file:
     file.write(textwrap.fill(text, width=6))

Note: it doesn't split text in the middle of word.

Upvotes: 2

Related Questions