1

I am trying to count all the As and Bs and Cs in all the .txt files I supply and make a .csv file that lists the counts one by one of all those letters.

The code here does all I want but only with the last file I supply instead of all of them.

What am I doing wrong?

import glob
import csv

#This will print out all files loaded in  the same directory and print them out
for filename in glob.glob('*.txt*'):
    print(filename)

#A B and C
substringA = "A"
Head1 = (open(filename, 'r').read().count(substringA))
substringB = "B"
Head2 = (open(filename, 'r').read().count(substringB))
substringC = "C"
Head3 = (open(filename, 'r').read().count(substringC))
header = ("File", "A Counts" ,"B Counts" ,"C Counts")
analyzed = (filename, Head1, Head2, Head3)

#This will write a file named Analyzed.csv
with open('Analyzed.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(header)
    writer.writerow(analyzed)
3
  • Is the code which is counting A B and C in the for loop or outside of it? Commented Aug 16, 2017 at 15:29
  • 2
    just move your counting code 4 spaces to the right for it to be inside for loop :) Commented Aug 16, 2017 at 15:33
  • I think that is exactly my issue. I don't know how I can loop my code that is counting through all files. Commented Aug 16, 2017 at 15:35

3 Answers 3

2

Indentation was missing and open Analyzed.csv in append mode a:

import glob
import csv

#This will print out all files loaded in  the same directory and print them out
for filename in glob.glob('*.txt*'):
    print(filename)

    #A B and C
    substringA = "A"
    Head1 = (open(filename, 'r').read().count(substringA))
    substringB = "B"
    Head2 = (open(filename, 'r').read().count(substringB))
    substringC = "C"
    Head3 = (open(filename, 'r').read().count(substringC))
    header = ("File", "A Counts" ,"B Counts" ,"C Counts")
    analyzed = (filename, Head1, Head2, Head3)

    #This will write a file named Analyzed.csv
    with open('Analyzed.csv', 'a') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(header)
        writer.writerow(analyzed)

EDIT: removed unsupported newline="" parameter

Sign up to request clarification or add additional context in comments.

3 Comments

Will overwrite Analyzed.txt
You must open the output file before the for or open it in append mode (but it will not erase previous run data).
I changed it to opening in append mode a
1

There's another small change you need to make: you need to open as append, not write, as well as indent. Note that when you open as append, you won't overwrite anything that was there before, so I added the portion at the top to delete anything already in the csv.

import glob
import csv


#This will delete anything in Analzyed.csv if it exists and replace it with the header
with open('Analyzed.csv','w') as csvfile:
    writer = csv.writer(csvfile)
    header = ("File", "A Counts" ,"B Counts" ,"C Counts")
    writer.writerow(header)

for filename in glob.glob('*.txt*'):
    print(filename)

    #A B and C
    substringA = "A"
    Head1 = (open(filename, 'r').read().count(substringA))
    substringB = "B"
    Head2 = (open(filename, 'r').read().count(substringB))
    substringC = "C"
    Head3 = (open(filename, 'r').read().count(substringC))
    header = ("File", "A Counts" ,"B Counts" ,"C Counts")
    analyzed = (filename, Head1, Head2, Head3)

    #This will write a file named Analyzed.csv
    with open('Analyzed.csv', 'a', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(analyzed)

Above is my solution keeping as much of your code untouched as possible. Ideally, though, you would only open the file once, at the beginning of the file. This is how you would do that:

import glob
import csv


with open('Analyzed.csv','w') as csvfile:
    writer = csv.writer(csvfile)
    header = ("File", "A Counts" ,"B Counts" ,"C Counts")
    writer.writerow(header)

    for filename in glob.glob('*.txt*'):
        print(filename)

        #A B and C
        substringA = "A"
        Head1 = (open(filename, 'r').read().count(substringA))
        substringB = "B"
        Head2 = (open(filename, 'r').read().count(substringB))
        substringC = "C"
        Head3 = (open(filename, 'r').read().count(substringC))
        analyzed = (filename, Head1, Head2, Head3)

        writer.writerow(analyzed)

2 Comments

Thank you so much. That works well. How to I avoid that it writes the head of the table multiple times. writer.writerow(header) do this just the very first time.
Whoops, I didn't notice that part, I'll add a fix
0

You can try this:

from itertools import chain
from collections import Counter
for filename in glob.glob('*.txt*'):
     data = chain.from_iterable([list(i.strip("\n")) for i in open(filename)])

     the_count = Counter(data)
     with open('Analyzed.csv', 'w', newline='') as csvfile:
         writer = csv.writer(csvfile)
         writer.writerow(filename)
         writer.writerow("A count: {}".format(the_count["A"]))
         writer.writerow("B count: {}".format(the_count["B"]))
         writer.writerow("C count: {}".format(the_count["C"]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.