0

New to python and programming in general, I'm struggling to get this program to run correctly. It has to:

  1. Read a text file, if the file doesn't exist it has to direct the person to re-input the text file. I have this part working.
  2. Count the lines, words in each line, and vowels in each line and output those amounts to a text file.
  3. Count the total number of words and vowels and output that at the bottom of the text file.
  4. I can't import anything other than OS for this. I don't know how to use the list function but I could probably use it in the code, essentially if I haven't used it and it's a better option I probably haven't learned it in class yet.

So the input test file says :

"This is a

test file

to see if

the program works."

The output text file should say:

Line Number: 1

Number of vowels in line 1: 3

Number of words in line 1: 3

Line Number: 2

Number of vowels in line 2: 3

Number of words in line 2: 2

// etc. Then at the bottom:

Total number of vowels in the file: 14

Total number of words in the file: 11

Instead, depending on the loop statement I try to use I either get infinite lines, two lines, or 8 lines. And the count for words and vowels is off.

Here's what I have so far based on what we've learned in class:

fileIn = open(input("File name: "), 'r')
fileOut = open("answer.txt", 'w')

numLines = 0

totVowels = 0
totWords = 0
    
for line in fileIn:
    line = fileIn.readline()
    if line != "":
        numLines += 1
        numWords = len(line.split(" "))
        fileOut.write("Line number: %0d" % numLines)
        fileOut.write("\n")
        numA = line.count('A')
        numE = line.count('E')
        numI = line.count('I')
        numO = line.count('O')
        numU = line.count('U')
        numLa = line.count('a')
        numLe = line.count('e')
        numLi = line.count('i')
        numLo = line.count('o')
        numLu = line.count('u')
        numVowels = numA + numE + numI + numO + numU + numLa + numLe + numLi + numLo + numLu
        fileOut.write("Number of vowels in line %0d: %0d" %(numLines, numVowels))
        fileOut.write("\n")
        fileOut.write("Number of words in line %0d: %0d" %(numLines, numWords))
        fileOut.write("\n")
        fileOut.write("\n")
    else:
        for lines in fileIn.readlines():
            words2 = lines.split()
            totWords += len(words2)
            if 'a' in words2:
                totVowels += 1
            elif 'e' in words2:
                totVowels += 1
            elif 'i' in words2:
                totVowels += 1
            elif 'o' in words2:
                totVowels += 1
            elif 'u' in words2:
                totVowels += 1
            elif 'A' in words2:
                totVowels += 1
            elif 'E' in words2:
                totVowels += 1
            elif 'I' in words2:
                totVowels += 1
            elif 'O' in words2:
                totVowels += 1
            elif 'U' in words2:
                totVowels += 1
            else:
                fileOut.write("\n")
                fileOut.write("+++++++++++++++++")
                fileOut.write("\n")
                fileOut.write("Total number of vowels in file: %0d" % totVowels)
                fileOut.write("\n")
                fileOut.write("Total number of words in file: %0d" % totWords)
                
                        

print("answer.txt file created.")
fileIn.close()
fileOut.close()

I honestly am really lost at this point, I've been going through my notes frantically trying to figure out what I'm missing but I'm hitting a wall, I'm tapped out mentally. I feel like I'm being thrown in the deep end but still haven't learned to swim yet. Any help or advise is appreciated.

Soren
  • 3
  • 4
  • You should fix the code *indentation* first. Secondly, the logic and code can be modularized and make it simpler. For example, use helper functions to ```count_words()``` and ```count_vowels()```? – Daniel Hao Mar 05 '23 at 01:31
  • Also rather than adding to the variables for each match, using `line.lower().count("aeiou")` for example would save you a lot of duplicate code (and therefore potential bugs). But your biggest issue is that you're first opening the input file with `w`, rather than `r+`. See [the docs](https://docs.python.org/3.8/library/functions.html#open) and [this summary](https://stackoverflow.com/questions/1466000/difference-between-modes-a-a-w-w-and-r-in-built-in-open-function#1466036). – Zac Anger Mar 05 '23 at 01:37
  • I'm reading the input file with 'r'. The 'w' is writing to the output file. – Soren Mar 06 '23 at 00:28
  • Daniel, thank you for telling me about helper functions! I didn't know what they were called or how to use them, but now I do and I greatly appreciate you for it! – Soren Mar 06 '23 at 17:38

2 Answers2

0

It is working up to this point:

for line in fileIn:

What this does is iterate over the lines in fileIn. So within that loop, line is a str with the text of one line. Count the number of words and vowels of that, and write those results to the output file. Then add those results to the totals. The loop will resume with the next lines.

Hence, you do not need to call readline() or readlines()

Then after the loop, write the totals to the output file.

So it should look something like this

totalVowels = 0
totalWords = 0
for line in fileIn:
    numVowels = count_vowels(line)
    numWords = count_words(line)
    write(numVowels, numWords)
    totalVowels += numVowels
    totalWords += numWords
write(totalVowels)
write(totalWords)
Emanuel P
  • 1,586
  • 1
  • 6
  • 15
  • If I write the totals after the loop it won't count them line by line, so the output won't look the way it's supposed to. – Soren Mar 06 '23 at 00:17
  • Yes, it will. Inside the loop you count and output the numbers per line. Then you add those numbers to variables that keep the totals of all lines. And then after the loop, you write those variables. – Emanuel P Mar 06 '23 at 00:38
  • Took me a while to figure out how to use def for the helper functions, specifically to count the vowels. I ended up using what I was doing earlier for it. Thank you for the help, I wouldn't have managed without you. – Soren Mar 06 '23 at 17:36
0

First of all, I'd recommend using the following to read lines. This will remove your if/else condition (I'm not exactly sure why you're using it):

    with open(filename) as f:
        lines = f.read().splitlines() 

This method removes newlines and allow you to easily read words in each line without having to worry about side cases. This will return you a list of strings, where each item will be a line in your document.

Also, instead of checking each vowel individually, you can use the in operator to make your code easier to debug. So, something like this would work:

for word in line:
   for letter in word:
       if letter.lower() in ['a', 'e', 'i', 'o', 'u']:
           vowels += 1

Now, all you have to do is implement what you already have and figure out a way where you can read the file, traverse each line in the file, then traverse each individual word and use the for loop above to get the number of vowels.

David AM
  • 115
  • 10
  • Using read().splitlines() prevents me from using anything else I know how to use. I get the error "AttributeError: 'list' object has no attribute split" for instance. I was using the if/else statement so it would count each line and put in the counts for the vowels and words of each line without the counts being cumulative and so the ending total count I needed would happen at the end of the file instead of in the middle. – Soren Mar 06 '23 at 00:08