Python Forum
A file for every person of a list
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A file for every person of a list
#1
Hello, I have the code below that finds a person(LookFor=) from a dialogue file and creates for him a new file with his name and the words he have said. Is it possible to automate this and create a file for every person that is in the dialogue file instead of writing one name at a time?
I am thinking to have another file with the list of names and somehow to check it with the dialogue files but I do not know how to do it. Any help please?

import os,re
lines = []
exportedLines = []

LookFor = 'Rich Smith'

excludedNames = re.compile(r'^(?!:)|(:| :)?')

with open('sample.txt') as dialogue:
    lines = dialogue.readlines()
for line in lines:
   mo = excludedNames.search(line)
   if line.startswith(LookFor):
       exportedLines += [line]
   elif line.startswith(LookFor) == False and lines[lines.index(line)-1].startswith(LookFor)== True and mo == None:
       exportedLines += [line]
with open('./%sWords.txt' % (LookFor),'w') as publish :
    publish.write("".join(exportedLines))        
The input file sample.txt contains this:
Rich Smith: I'm going to attend a concert on Saturday.
Do you have any special plans?
Peter Aderson (the boss) : No, I'm going to relax. What did you do last weekend?
Rich Smith: Last weekend, I went to visit my friends in San Francisco. What did you do?
Peter Aderson (the boss): I played soccer with some friends.
Mary Sarah: Hello
John Daisa: hi


The output file RichSmith.txt
Output:
Rich Smith: I'm going to attend a concert on Saturday. Rich Smith: Last weekend, I went to visit my friends in San Francisco. What did you do?
I need to have for output:
Rich.txt
Rich Smith: I'm going to attend a concert on Saturday
Rich Smith: Last weekend, I went to visit my friends in San Francisco. What did you do?

PeterAderson.txt
Peter Aderson(the boss): No, I'm going to relax. What did you do last weekend?
Peter Aderson (the boss): I played soccer with some friends.

MarySarah.txt
Mary Sarah: Hello

JohnDaisa.txt
John Daisa: hi
Reply
#2
So you don't need line "Do you have any special plans?"

Who is PeterSmith?
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
Yes, you are right, I lost a line, of course I need it.
I changed something to excludedNames and I lost a line.
I am trying to find it.
It is PeterAderson.txt, I corrected it
Reply
#4
As this is second thread about this problem I suspect that this is assignment. One should always learn, whether in class or in this forum. So I try to describe one potential approach.

For starters word of caution:

Quote:Regex is a pretty big hammer. Of course, you should know how to use that hammer if you really need a big hammer, but nevertheless it's a hammer. And you know what they say about hammers - if all you got is a hammer, everything looks like a nail.

Jamie Zawinsky is credited with the phrase "Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

Using regex is troublesome because you may quickly end up with something that may work but in a week or month you lost the intuition of the expression, unable to tell what this thing is doing without diving into its intricacies all over again.

In this particular case I don't see need for hammer as there are no nails.

What we need:

- read a file
- get actors names and their text from file rows
- write text by actors into file(s)

Read the file.

It's simple. We use open. It's a good practice to indicate mode ('r'). As file object is iterable we can iterate rows directly:

with open('somefile.txt', 'r') as script:
    for row in script:
        # do something useful
Get actors names and text from rows

If we observe example file then we can see:

- actors are before :
- some actor names have space between name and :
- some actor names contain additional information which should be stripped: (the boss) NB! This is not actually in assignment, I assigned it myself.
- some lines of text are without actor name (continuation of text)

So how we should approach this? One way is to process every line, split line on : and unpack result into variables, something like that:

actor, text = line.split(':')
If we run this we will find out that it will fail on rows there is no actor name and therefore no :. Python will raise ValueError because (a) there is no sign on what to split (b) .split method returns list with only one item in it © there is no value to assign to text

>>> 'abc'.split(':')
['abc']
>>> actor, text = 'abc'.split(':')
/../
ValueError: not enough values to unpack (expected 2, got 1)
Are we stuck? No, on the contrary. This error enables use use pythonic EAFP style of coding. How? We process first line and get actor name and text, on second line there is no actor name and therefore error is raised. We can just assign whole line to text without changing actor name defined while processing previous line:

for line in script:
    try:
        actor, text = line.split(':')
    except ValueError:
        text = line
Now we have to think about data structure we will keep the results. One obvious way is to use defaultdict but I chose ordinary dictionary with .setdefault method. In spoken language: 'if we encounter name first time create a key from that name and assign empty list as value and and in any case (whether key existed or not) append text into this list'. This enables us to create dictionary where key is actor name and value is list of text lines.

As we earlier observed need for some 'cleaning' then we should do it here, otherwise we may end with different keys for same actor. So we write this (assuming thad we have dictionary named d), stripping whitespaces and (the boss) part:

d.setdefault(actor.split('(')[0].strip(), []).append(text.strip())
The whole code to read file and save data into dictionary can be something like this:

d = {}

with open('sample.txt', 'r') as script:
    for line in script:
        try:
            actor, text = line.split(':')
        except ValueError:
            text = line
        d.setdefault(actor.split('(')[0].strip(), []).append(text.strip())
Write text by actors into file(s).

We have dictionary and need to create files and write needed text into them.

We have actor names as dictionary keys. We need to format these to get suitable file names (camelcase). f-string is obvious choice if using Python <= 3.6. With every key we should split it on whitespace, join back together without whitespace and add extension (k is dictionary key):

f"{''.join(k.split(' '))}.txt"
In every line we should write actor name and one line of text. Here we can also take advantage of f-strings. File operation(s) is already covered so we combine our knowledge into code. In spoken language: 'iterate over keys and values, create filename (and file) from key, for every item in values write row in file in form of key: value'

for k, v in d.items():
    with open(f"{''.join(k.split(' '))}.txt", 'w') as outing:
        for value in v:
            outing.write(f'{k}: {value}\n')
So this is how whole code could look like:

d = {}

with open('sample.txt', 'r') as script:
    for line in script:
        try:
            actor, text = line.split(':')
        except ValueError:
            text = line
        d.setdefault(actor.split('(')[0].strip(), []).append(text.strip())

for k, v in d.items():
    with open(f"{''.join(k.split(' '))}.txt", 'w') as outing:
        for value in v:
            outing.write(f'{k}: {value}\n')
As this is probably assignment I deliberately didn't address the issue that line without name should be appended to previous line and altered slightly conditions (stripping '(the boss)')
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  OOP hellp (simple class person) onit 4 2,530 Jul-14-2020, 06:54 PM
Last Post: onit
  Writing list as a file, then reading that file as a list Zoastria_Balnala 3 2,578 Oct-17-2019, 07:54 PM
Last Post: Zoastria_Balnala
  Discord Bot - If Person Mentions Role badmuchachob 0 2,199 Jan-30-2019, 06:39 PM
Last Post: badmuchachob
  Installing Homebrew on my mac; non computer-savvy person duongtn34 1 1,878 Oct-23-2018, 09:11 AM
Last Post: Larz60+
  Why Person() takes no arguments dianefly 3 30,985 Oct-22-2018, 04:15 PM
Last Post: dianefly
  Installing Homebrew on my mac; non computer-savvy person hohen036 3 3,811 Oct-12-2018, 11:02 PM
Last Post: Larz60+
  Can you tell me where this person got the version of Python that he's using? nelsonkane 8 5,049 Mar-11-2018, 11:10 AM
Last Post: gptura

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020