I am working on this coding problem:
Count the number of words & lines that have more than X vowels for every Y words in every Z line.
Basically the input string has multiple lines and I need to count words that have X or more vowels in them. But the constraint is I need to consider only every Zth line as well as only every Yth word in those lines.
For example let's say I need to count every 3rd word that has 2 or more vowels in every 3rd line. So here X=2, Y=3, Z=3.
Input string:
"1.When I first brought my cat home.
2.It cost a lot to adopt her.
3.I paid forty dollars for it.
4.And then I had to buy litter, a litterbox.
5.Also bought food, and dishes for her to eat out of.
6.There's a **leash** law for cats in Fort **Collins**.
7.If they're not in your yard they have to be on a leash.
8.Anyway, my cat is my best friend.
9.I'm glad I got her.
10.She sleeps under the covers with me when it's cold."
Output should be:
Word Count: 2, Line Count: 1
So based on criteria of Z=3, i.e. "count every 3rd line", the lines to be considered are lines 3, 6, 9.
In these lines we need to count Y=3, i.e. every 3rd word. So the words to be considered are forty, it from line 3, leash, cats, Collins from line 6, and I from line 9.
Given these criteria, the matching words with 2 or more vowels are found only in line 6 with words leash and Collins, so the output is WordCount = 2
and LineCount = 1
.
class StringCount:
lines = list();
totalMatchedLines = 0;
totalMatchedWords = 0;
matchedChars = 0;
def __init__(self, inputString, vowelCount, skipWords, skipLines, wordDelimiter, lineDelimiter):
self.inputString = inputString;
self.vowelCount = vowelCount;
self.skipWords = skipWords;
self.skipLines = skipLines;
self.wordDelimiter = wordDelimiter;
def splitLines(self):
if self.inputString.strip() == "":
print ("Please enter a valid string!");
return False;
self.lines = self.inputString.splitlines();
def splitWords(self):
self.matchedWords = 0;
self.matchedLines = 0;
self.linesLength = len(self.lines);
if self.linesLength < self.skipLines:
print ("Input string should be greater than {0}" .format(self.skipLines));
return False;
lineCount = self.skipLines - 1;
wordCount = self.skipWords - 1;
lineInUse = "";
words = list();
while (lineCount < self.linesLength):
self.matchedWords = 0;
self.matchedLines = 0;
self.words = self.lines[lineCount].split();
self.wordsLength = len(self.words);
wordCount = self.skipWords - 1;
while (wordCount < self.wordsLength):
self.matchedChars = 0;
for i in self.words[wordCount].lower():
if(i=='a' or i=='e' or i=='i' or i=='o' or i=='u'):
self.matchedChars += 1;
if self.matchedChars >= self.vowelCount:
self.matchedWords += 1;
wordCount += self.skipWords;
if self.matchedWords > 0:
self.matchedLines += 1;
self.totalMatchedWords += self.matchedWords;
self.totalMatchedLines += self.matchedLines;
lineCount += self.skipLines;
print ("WordCount = %s" % (self.totalMatchedWords));
print ("LineCount = %s" % (self.totalMatchedLines));
Code to invoke the class:
mystring = "1.When I first brought my cat home.
2.It cost a lot to adopt her.
3.I paid forty dollars for it.
4.And then I had to buy litter, a litterbox.
5.Also bought food, and dishes for her to eat out of.
6.There's a **leash** law for cats in Fort **Collins**.
7.If they're not in your yard they have to be on a leash.
8.Anyway, my cat is my best friend.
9.I'm glad I got her.
10.She sleeps under the covers with me when it's cold.";
myobjectx = StringCount(myString, 2, 3, 3, " ", "\n");
myobjectx.splitLines();
myobjectx.splitWords();
Since this is my first piece of Python code, I wanted to check how to optimize this code in both performance and line optimization. Is there any inbuilt functionality to shorten the multiple while
loops and the for
loop?
optimize this code in both performance and line optimization
readability (→maintainability) first! \$\endgroup\$mystring
spans multiple lines, and needs to be triple-quoted. \$\endgroup\$