matlabwhile-loopfgetslow-level-io

Find a Name in an Email (Low-Level I/O)


Round 2: Picking out leaders in an email Alrighty, so my next problem is trying to figure out who the leader is in a project. In order to determine this, we are given an email and have to find who says "Do you want..." (capitalization may vary). I feel like my code should work for the most part, but I really have an issue figuring out how to correctly populate my cell array. I can get it to create the cell array, but it just puts the email in it over over again. So each cell is basically the name.

function[Leader_Name] = teamPowerHolder(email)

email = fopen(email, 'r'); %// Opens my file
lines = fgets(email); %// Reads the first line

conversations = {lines}; %// Creates my cell array


while ischar(lines) %// Populates my cell array, just not correct
    Convo = fgets(email);
    if Convo == -1 %// Prevents it from just logging -1 into my cell array like a jerk
        break; %// Returns to function
    end
    conversations = [conversations {lines}]; %// Populates my list
end
Sentences = strfind(conversations,'Do you want'); %// Locates the leader position


Leader_Name = Sentences{1}; %// Indexes that position

fclose(email);
end

What I ideally need it to do is find the '/n' character (hence why I used fgets) but I'm not sure how to make it do that. I tried to have my while loop be like:

while lines == '/n'

but that's incorrect. I feel like I know how to do the '/n' bit, I just can't think of it. So I'd appreciate some hints or tips to do that. I could always try to strsplit or strtok the function, but I need to then populate my cell array so that might get messy.

Please and thanks for help :)

Test Case:
Anna: Hey guys, so I know that he just assigned this project, but I want to go ahead   and get started on it.
Can you guys please respond and let me know a weekly meeting time that will work for you?

Wiley: Ummmmm no because ain't nobody got time for that.

John: Wiley? What kind of a name is that? .-.

Wiley: It's better than john. >.>

Anna: Hey boys, let's grow up and talk about a meeting time.
Do you want to have a weekly meeting, or not?

Wiley: I'll just skip all of them and not end up doing anything for the project anyway.
So I really don't care so much.

John: Yes, Anna, I'd like to have a weekly meeting.
Thank you for actually being a good teammate and doing this. :)

out2 = teamPowerHolder('teamPowerHolder_convo2.txt')
    => 'Anna'

Solution

  • The main reason why it isn't working is because you're supposed to update the lines variable in your loop, but you're creating a new variable called Convo that is updating instead. This is why every time you put lines in your cell array, it just puts in the first line repeatedly and never quits the loop.


    However, what I would suggest you do is read in each line, then look for the : character, then extract the string up until the first time you encounter this character minus 1 because you don't want to include the actual : character itself. This will most likely correspond to the name of the person that is speaking. If we are missing this occurrence, then that person is still talking. As such, you would have to keep a variable that keeps track of who is still currently talking, until you find the "do you want" string. Whoever says this, we return the person who is currently talking, breaking out of the loop of course! To ensure that the line is case insensitive, you'll want to convert the string to lower.

    There may be a case where no leader is found. In that case, you'll probably want to return the empty string. As such, initialize Leader_Name to the empty string. In this case, that would be []. That way, should we go through the e-mail and find no leader, MATLAB will return [].

    The logic that you have is pretty much correct, but I wouldn't even bother storing stuff into a cell array. Just examine each line in your text file, and keep track of who is currently speaking until we encounter a sentence that has another : character. We can use strfind to facilitate this. However, one small caveat I'll mention is that if the person speaking includes a : in their conversation, then this method will break.

    Judging from the conversation that I'm seeing your test case, this probably won't be the case so we're OK. As such, borrowing from your current code, simply do this:

    function[Leader_Name] = teamPowerHolder(email)
    
    Leader_Name = []; %// Initialize leader name to empty
    name = [];    
    
    email = fopen(email, 'r'); %// Opens my file
    lines = fgets(email); %// Reads the first line
    
    while ischar(lines)
    
        % // Get a line in your e-mail
        lines = fgets(email);
    
        % // Quit like a boss if you see a -1
        if lines == -1
            break;
        end
    
        % // Check if this line has a ':' character.
        % // If we do, then another person is talking.
        % // Extract the characters just before the first ':' character
        % // as we don't want the ':' character in the name
        % // If we don't encounter a ':' character, then the same person is
        % // talking so don't change the current name
        idxs = strfind(lines, ':');
        if ~isempty(idxs)
            name = lines(1:idxs(1)-1);
        end    
    
        % // If we find "do you want" in this sentence, then the leader
        % // is found, so quit.
        if ~isempty(strfind(lower(lines), 'do you want'))
            Leader_Name = name;
            break;
        end
    end
    

    By running the above code with your test case, this is what I get:

    out2 = teamPowerHolder('teamPowerHolder_convo2.txt')
    
    out2 = 
    
    Anna