SenKi
SenKi

Reputation: 53

Is there a way to write bits of text to different files if different conditions are met?

I have this text which i will share a part from,

ROMEO

But, soft! what light through yonder window breaks? It is the east, and Juliet is the sun.

JULIET

Ay me!

ROMEO

She speaks: O, speak again, bright angel! for thou art.

JULIET

O Romeo, Romeo! wherefore art thou Romeo? Deny thy father and refuse thy name;

ROMEO

Shall I hear more, or shall I speak at this?.

I want to write a loop that looks for the name in the line and saves the contents after it to a specific file, in this case if "ROMEO" is the word found every line after it will be saved to "Romeo.txt" until the word "JULIET" is found then all content is saved to "Juliet.txt". I tried coding it myself with an amalgamation of loops and if statements but it got me to nowhere. handle = open("romeo-full.txt") skipper = "ROMEO"

handle = open("romeo-full.txt")
skipper = "ROMEO"

for line in handle:
    line = line.strip()     
    while skipper == "ROMEO":
        print(line) #This would be the write to file code
        if line.startswith("ROMEO"):
            skipper = "JULIET"
            break
        else:
            continue

    while skipper == "JULIET":
        print(line) #This would be the write to file code
        if line.startswith("ROMEO"):
            skipper = "ROMEO"
            break
        else:
            continue

The output is basically "ROMEO" lines looping, which i understood it's coming from the while loop going through the first line forever, but i couldn't figure a way out closer to what i want than this.

Upvotes: 1

Views: 61

Answers (2)

Tomerikoo
Tomerikoo

Reputation: 19414

One way to avoid the duplicated code will be to use the headers in the main file as "choosers" for the what file to write to. Something like:

with open("romeo-full.txt") as handle, \
     open("romeo.txt", 'w') as r_f, \
     open("juliet.txt", 'w') as j_f:

    file_chooser = {"ROMEO": r_f,
                    "JULIET": j_f}

    for line in handle:
        try:
            cur_file = file_chooser[line.strip()]
        except KeyError:     
            cur_file.write(line)

The purpose of the try/except block is to change the cur_file only when we encounter one of the headings (and then skip it).


One way to avoid that is to use dict's get method with cur_file as the default (so it changes only on headers):

with open("romeo-full.txt") as handle, \
     open("romeo.txt", 'w') as r_f, \
     open("juliet.txt", 'w') as j_f:

    file_chooser = {"ROMEO": r_f,
                    "JULIET": j_f}
    cur_file = r_f
    for line in handle:
        cur_file = file_chooser.get(line.strip(), cur_file)

        cur_file.write(line)

The downside here is that the headers will also be written each time to the files.

Upvotes: 1

Nathan
Nathan

Reputation: 3648

You can write to multiple files like so:

with open('example1.txt', 'w') as file_1 \
        , open('example2.txt', 'w') as file_2 \
        , open('example3.txt', 'w') as file_3 \
        , open("romeo-full.txt", 'r') as handle:
    for line in handle:
        if condition_1:
            file_1.write(line)
        elif condition_2:
            file_2.write(line)
        elif condition_3:
            file_3.write(line)

The reason you should always use with instead of open and close is because if for some reason you don't close (like the program crashing or you forgetting to add it), the file will not be closed, taking up space. I've seen it happen that files that are frequently opened and not closed cause servers to crash!

Upvotes: 0

Related Questions