0

I'm currently working on this assignment where I have to convert essentially this input csv file

into this written csv file

here's my code that's currently creating the csv file in my folder but it's not actually writing anything in it.

import csv

def read_calculate():
    dict1 = {}
    with open('sunspots.csv','r') as file:
        csv_reader = csv.reader(file, delimiter=',')
        for row in csv_reader:
            year_month = row[0] + row[1]

            if year_month in dict1:
                if(row[4].isnumeric() and int(row[4])!= -1):
                   dict1[year_month]+= int(row[4])
                else:
                   if(row[4].isnumeric() and int(row[4])!=-1):
                       dict1[year_month]=int(row[4])
                   else:
                       dict1[year_month]=0

        file.close()
        return dict1


def write_to_file(dict1):
    with open('Monthtotal.csv','w',newline='') as write_file:
        writer = csv.writer(write_file)
        for key in dict1.keys():
            line = key[0:4],k[4:6],str(dict1[key])
            writer.writerow(line)

    write_file.close()



if __name__=='__main__':
    dict1 = read_calculate()
    write_to_file(dict1)
4
  • We cannot test your code with those images. Commented Nov 3, 2018 at 21:29
  • Possible duplicate of portable way to write csv file in python 2 or python 3 Commented Nov 3, 2018 at 21:35
  • @DManokhin thanks for mentionning this excellent Q&A :) but this isn't the issue. OP is obviously using python 3 and uses the proper newline="" statement. Commented Nov 3, 2018 at 21:36
  • BTW you don't need the close() statements since you're using contexts for your files. Commented Nov 3, 2018 at 21:37

2 Answers 2

2

the test

if year_month in dict1:

"protects" dict1 from being updated when reading the file. So when you write the file you get no data.

I suppose you want to deindent the else part:

if year_month in dict1:
    if(row[4].isnumeric() and int(row[4])!= -1):
       dict1[year_month]+= int(row[4])
else:
   if(row[4].isnumeric() and int(row[4])!=-1):
       dict1[year_month]=int(row[4])
   else:
       dict1[year_month]=0

but there are smarter approaches like collections.Counter:

import collections
dict1 = collections.Counter()

then in the loop, just a test to ensure that the data is a number then:

if(row[4].isnumeric() and int(row[4])!= -1):
   dict1[year_month] += int(row[4])
else:
   dict1[year_month] += 0  # add nothing, but "creates" the key if doesn't exist

you need the else part (which seem clumsy, yeah I know) so you create all month keys, even empty ones, else your csv file will have holes. the alternative is not to loop on the keys when writing your dictionary (dicts aren't ordered until python 3.6) but on the hardcoded month values. Counter will yield 0 on a non-existing key.

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

3 Comments

wow actually works now thanks! i haven't learned collections yet. is it strictly so i can use counter or are there other things?
collections.defaultdict(int) works the same in that context. And it's faster than testing if the key is there.
if i were to calculate the average of the 4th column for 12 rows how would i do this?
0

dict1 starts empty, and you only add to it if the year_month value is already found in that empty dict, which it obviously never will be.

I'm not quite sure what the logic is supposed to be here, but you presumably need some way of setting a default value when the year_month is not found.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.