0

This is a follow up to this question I posted earlier:

How to return 1 if the first letter of a word is a vowel, return 0 otherwise. Mapper (MapReduce) problem

I am having trouble returning 1 only if the last letter of a word is a vowel.

What I have so far is:

import sys
import re

pattern = re.compile("^[a-z]+$")  # matches purely alphabetic words
starting_vowels = re.compile("(^[aeiouAEIOU])")  # matches starting vowels
ending_vowels = re.compile("[aeiouAEIOU]$")  # matches ending vowels
starting_vowel_match = 0
ending_vowel_match = 0

for line in sys.stdin:
    line = line.strip()  # removes leading and trailing whitespace
    words = line.lower().split()  # splits the line into words and converts to lowercase
    for word in words:
        starting_vowel_match = 1 if starting_vowels.match(word[0]) else 0
        # ternary operator, word[0] is the first letter of the word
        ending_vowel_match = 1 if ending_vowels.match(word[-1]) else 0

        for letter in word:
            if pattern.match(letter):
                print("%s 1" % letter, starting_vowel_match, ending_vowel_match)
                starting_vowel_match = 0
                ending_vowel_match = 0

The output I am getting is when I run this with a text file with the string "its a beautiful life" is:

i 1 1 0
t 1 0 0
s 1 0 0
a 1 1 1
b 1 0 0
e 1 0 0
a 1 0 0
u 1 0 0
t 1 0 0
i 1 0 0
f 1 0 0
u 1 0 0
l 1 0 0
l 1 0 1
i 1 0 0
f 1 0 0
e 1 0 0

It seems as though the last l character is returning a 1 in the fourth column because the last letter in the string life is e. What I would like is for only the last e to output 1 in the fourth column, since it is the last letter of a word.

The output I want is:

i 1 1 0
t 1 0 0
s 1 0 0
a 1 1 1
b 1 0 0
e 1 0 0
a 1 0 0
u 1 0 0
t 1 0 0
i 1 0 0
f 1 0 0
u 1 0 0
l 1 0 0
l 1 0 0
i 1 0 0
f 1 0 0
e 1 0 1
Zaku
  • 180
  • 6
  • 3
    You don't need a regular expression for this. `if c in 'aeiou':` is more efficient. And what is that final loop for? Why do you do the letters individually? – Tim Roberts Apr 21 '23 at 06:50
  • @TimRoberts This is part of an assignment for a class. That was code given to me by my professor. I was told not to change it. – Zaku Apr 21 '23 at 07:31
  • @TimRoberts Looking over everything, I believe the first regex is to filter out special characters in the output. – Zaku Apr 21 '23 at 20:33

5 Answers5

1

Try this:

import sys

for line in sys.stdin:
    line = line.strip()
    for word in line.lower().split():
        if len(word) == 1:
            print(word[0], 1, *((1, 1) if word[0] in 'aeiou' else (0, 0)))
        else:
            print(word[0], 1, 1 if word[0] in 'aeiou' else 0, 0)
            print(*(f'{letter} 1 0 0' for letter in word[1: -1]), sep='\n')
            print(word[-1], 1, 0, 1 if word[-1] in 'aeiou' else 0)

Output (with line = "its a beautiful life"):

i 1 1 0
t 1 0 0
s 1 0 0
a 1 1 1
b 1 0 0
e 1 0 0
a 1 0 0
u 1 0 0
t 1 0 0
i 1 0 0
f 1 0 0
u 1 0 0
l 1 0 0
l 1 0 0
i 1 0 0
f 1 0 0
e 1 0 1
Riccardo Bucco
  • 13,980
  • 4
  • 22
  • 50
  • I forgot to mention one of the constraints is that the output should not return any special characters, just letters. I believe that's why my professor included the first regex. Your code is very concise and I am not very good at Python, so I am still analyzing it. – Zaku Apr 23 '23 at 01:44
0

I think you should pass in the word to regex match, not just the last letter. Your regex already searches for a word beginning or ending with a vowel.

So you want:

starting_vowel_match = 1 if starting_vowels.match(word) else 0
# ternary operator, word[0] is the first letter of the word
ending_vowel_match = 1 if ending_vowels.match(word) else 0
Oded Ben Dov
  • 9,936
  • 6
  • 38
  • 53
0

If the question is asking about a mapper, I assume you need some sort of functional solution? Here I'm using the first sentence of Lorem Ipsum as an example:

paragraph = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."""

cleaned_paragraph = ''.join(i for i in paragraph if i not in ['.', ',', '?', '!', ':', ';']) # remove puctuation
words = cleaned_paragraph.split()  # get individual words

def mapper(word: str) -> int:
    return 1 if word[-1] in 'aeiou' else 0 

res = list(map(mapper, words))

Out:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1]
NotAName
  • 3,821
  • 2
  • 29
  • 44
0

Replace your

        for letter in word:
            if pattern.match(letter):
                print("%s 1" % letter, starting_vowel_match, ending_vowel_match)
                starting_vowel_match = 0
                ending_vowel_match = 0

with this:

        for i, letter in enumerate(word):
            if pattern.match(letter):
                print(
                    "%s 1" % letter,
                    starting_vowel_match * (i == 0),
                    ending_vowel_match * (i == len(word) - 1)
                )

With enumerate you know where you are in the word.

Kelly Bundy
  • 23,480
  • 7
  • 29
  • 65
0

Use of a regular expression seems like overkill for this. You just need a couple of simple functions - something like this:

VOWELS = set('aeiouAEIOU')

def is_leading_vowel(word):
    return 1 if word and word[0] in VOWELS else 0

def is_trailing_vowel(word):
    return 1 if word and word[-1] in VOWELS else 0
DarkKnight
  • 19,739
  • 3
  • 6
  • 22