9

I am supposed to add a specific label to my CSV file based off conditions. The CSV file has 10 columns and the third, fourth, and fifth columns are the ones that affect the conditions the most and I add my label on the tenth column. I have code here which ended in an infinite loop:

import csv
import sys

w = open(sys.argv[1], 'w')
r = open(sys.argv[1], 'r')

reader = csv.reader(r)
writer = csv.writer(w)

for row in reader:
    if row[2] or row[3] or row[4] == '0':
        row[9] == 'Label'
        writer.writerow(row)

w.close()
r.close()

I do not know why it would end in an infinite loop.

EDIT: I made a mistake and my original infinite loop program had this line:

w = open(sys.argv[1], 'a')

I changed 'a' to 'w' but this ended up erasing the entire CSV file itself. So now I have a different problem.

midori
  • 4,807
  • 5
  • 34
  • 62
Reginsmal
  • 127
  • 9

3 Answers3

8

You have a problem here if row[2] or row[3] or row[4] == '0': and here row[9] == 'Label', you can use any to check several variables equal to the same value, and use = to assign a value, also i would recommend to use with open.

Additionally you can't read and write at the same time in csv file, so you need to save your changes to a new csv file, you can remove the original one after and rename the new one using os.remove and os.rename:

import csv
import sys    
import os

with open('some_new_file.csv', 'w') as w, open(sys.argv[1], 'r') as r:
    reader, writer = csv.reader(r), csv.writer(w)
    for row in reader:
        if any(x == '0' for x in (row[2], row[3], row[4])):
            row[9] = 'Label'
        writer.writerow(row)

os.remove('{}'.format(sys.argv[1]))
os.rename('some_new_file.csv', '{}'.format(sys.argv[1]))
midori
  • 4,807
  • 5
  • 34
  • 62
  • Thank you this has prevented infinite loop in the program in append mode. However it didn't seem to have worked correctly as the label wasn't added. – Reginsmal Feb 12 '16 at 03:34
  • 1
    there is another problem, you can't open the same file for writing and reading – midori Feb 12 '16 at 03:35
  • I tried to change `sys.argv[1]` to be written to `test.csv` with the file I have to be read. However `test.csv` ended up the same as the original. – Reginsmal Feb 12 '16 at 03:43
  • you need to use w mode and new file, i updated the answer – midori Feb 12 '16 at 03:44
  • you can delete the original file after and rename new one if you want – midori Feb 12 '16 at 03:45
  • I have tried the new version and my new file, the one to have the labels, has become completely empty. Why would this happen? – Reginsmal Feb 12 '16 at 03:50
  • This seems to have worked! Thank you for your help. I do not know why it separates the labelled with the part that isn't but I'll have to work on that. EDIT: It turned out I needed to create the file through the program first. – Reginsmal Feb 12 '16 at 04:17
  • 2
    i figure it out, you had row[9] == 'Label' instead row[9] = 'Label' – midori Feb 12 '16 at 04:31
  • also i assume you want all lines in your new file even unchanged ones, i made changes and i added remove/rename files part – midori Feb 12 '16 at 04:37
4

You can write to a tempfile.NamedTemporaryFile and just use in to test for the "0" as you are matching a full string not a substring so you won't save anything by using any as you create a tuple of three elements so you may as well slice or just test for membership regardless, then you just replace the original file with shutil.move:

import csv
import sys    
from shutil import move
from tempfile import NamedTemporaryFile

with NamedTemporaryFile("w", dir=".", delete=False) as w, open(sys.argv[1]) as r:
    reader, writer = csv.reader(r), csv.writer(w)
    writer.writerows(row[:-1] + ['Label'] if "0" in row[2:5] else row 
                     for row in reader)

move(w.name, sys.argv[1])

sys.argv[1] is also you file name and a string so that is all you need to pass.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • i'm giving my bounty to you, since you are the only one who posted a good answer besides me – midori Feb 24 '16 at 21:47
0

I think the Problem is in lines

w = open(sys.argv[1], 'w')
r = open(sys.argv[1], 'r')

You are opening the same file for reading and writing.So try using different file name.

midori
  • 4,807
  • 5
  • 34
  • 62
user2823297
  • 37
  • 1
  • 6