AttributeError: 'str' object has no attribute 'csv' - python

I am trying to write a CSV file and I have code to create a document with a header file this code will take inputs to write to that same file.
class CSVFile:
def __init__(self, doctitle):
#creates the physical doc on the disk
#creates the header row in the .csv file
self.doctitle = doctitle
self.f = open(doctitle + ".csv", 'w+')
self.f.write("vianumber, innerdiameter, outerdiamter, ratio \n")
self.closedoc()
return
def appendrow(self, doctitle, vianumber, innerdiameter, outerdiamter, ratio):
#called for each measured via
self.f = open(doctitle + ".csv", 'a+')
self.f.write(vianumber, innerdiameter, outerdiamter, ratio)
self.closedoc()
return
def closedoc(self):
#filize the document
self.f.close()
return
The error message I get is the following:
CSVFile.appendrow("", "test", 2, 3, 4, 5)
Traceback (most recent call last):
File "<ipython-input-21-07d259b7d2fa>", line 1, in <module>
CSVFile.appendrow("", "test", 2, 3, 4, 5)
File "C:/Users/Brook/Desktop/Senior Design/CSV file script.py", line 23, in appendrow
self.f = open(doctitle + ".csv", 'a+')
AttributeError: 'str' object has no attribute 'f'

This is because you are not instantiating an object. Your call is CSVFile.appendrow("", "test", 2, 3, 4, 5).
Essentially, it means that for the self parameter of appendrow you are passing an empty string argument "".
Try something along lines of CSVFile("test").appendrow("test", 2, 3, 4, 5)
You have an error in the self.f.write call in your code as well, but I will let you fix that.

Your class and the way you use it have a lot of issues, such as:
You do not use the stored file name.
You do not use the standard CSV writer.
You do not use with blocks.
You do not create a class object.
You create unnecessary object attributes.
You pass the self parameter to an object method.
Here is an improved version of your code.
import csv
class CSVFile:
def __init__(self, doctitle):
self.doctitle = doctitle + ".csv"
with open(doctitle, 'w+') as f:
writer = csv.writer(f)
writer.writerow(["vianumber", "innerdiameter",
"outerdiamter", "ratio"])
def appendrow(self, vianumber, innerdiameter, outerdiamter, ratio):
#called for each measured via
with open(self.doctitle, 'a+') as f:
writer = csv.writer(f)
writer.writerow([vianumber, innerdiameter, outerdiamter, ratio])
#def closedoc(self): -- Not needed!
#filize the document
mycsv = CSVFile("foo")
mycsv.appendrow(2,3,4,5)

Related

How to set value of parent argument to child method?

I have a Paragraph class:
from googletrans import Translator
class Paragraph:
def __init__(self, text, origin_lang='en'):
self.text = text
self.origin_lang = origin_lang
def translate(self, dest_lang='ne'):
translator = Translator()
translation = translator.translate(text = self.text,
dest=dest_lang)
return translation.text
I made a subclass out of it:
class FileParagraph(Paragraph):
def __init__(self, filepath):
super().__init__(text=self.get_from_file())
self.filepath = filepath
def get_from_file(self):
with open(self.filepath) as file:
return file.read()
While Paragraph got the text directly as argument, the subclass generates the text from the get_from_file method.
However, I cannot seem to call the inherited translate method:
fp = FileParagraph("sample.txt")
print(fp.translate(dest_lang='de'))
That throws an error:
Traceback (most recent call last):
File "C:/main.py", line 66, in <module>
fp = FileParagraph("sample.txt")
File "C:/main.py", line 20, in __init__
super().__init__(text=self.get_from_file())
File "C:/main.py", line 25, in get_from_file
with open(self.filepath) as file:
AttributeError: 'FileParagraph' object has no attribute 'filepath'
One solution is to change the subclass init to:
def __init__(self, filepath):
self.filepath = filepath
self.text = self.get_from_file()
However, that means removing the initialization of super(). Is there another solution without having to remove super().__init__?
Or is this not even the case to make use of inheritance?
The error comes from calling the get_from_file method, which relies on self.filepath, before self.filepath is set. Simply changing the order of the two lines in __init__ fixes this
class FileParagraph(Paragraph):
def __init__(self, filepath):
# set member variable first
self.filepath = filepath
# then call super's init
super().__init__(text=self.get_from_file())
def get_from_file(self):
with open(self.filepath) as file:
return file.read()
i think that you should also give a value for the filepath while creating the object here
fp = FileParagraph("sample.txt")
you should also input a value for the filepath along with text
eg
fp = FileParagraph(text = "sample.txt", filepath = " ")

Why am i getting this error (TypeError: '_io.TextIOWrapper' object is not subscriptable) after the first iteration of my for loop?

The following code i wrote, will run one iteration with no problems. However i want it to loop through all of the values of x (which in this case there are 8). After it does the first loop through, when it goes to the second, i get an error on this line (t = f[x]['master_int'])
Traceback (most recent call last):
File "Hd5_to_KML_test.py", line 16, in <module>
t = f[x]['master_int']
TypeError: '_io.TextIOWrapper' object is not subscriptable
So it only outputs results (a .csv file and a .kml file) for BEAM0000. I was expecting it to loop through and output the two files for all 8 beams. What am I missing, why won't it loop through the other beams?
import h5py
import numpy as np
import csv
import simplekml
import argparse
parser = argparse.ArgumentParser(description='Creating a KML from an HD5 file')
parser.add_argument('HD5file', type=str)
args = parser.parse_args()
HD5file = args.HD5file
f = h5py.File(HD5file, 'r')
beamlist = []
for x in f:
t = f[x]['master_int']
for i in range(0, len(t), 1000):
time = f[x]['master_int'][i]
geolat = f[x]['geolocation']['lat_ph_bin0'][i]
geolon = f[x]['geolocation']['lon_ph_bin0'][i]
beamlist.append([time, geolat, geolon])
file = x + '.csv'
with open(file, 'w') as f:
wr = csv.writer(f)
wr.writerows(beamlist)
inputfile = csv.reader(open(file, 'r'))
kml = simplekml.Kml()
for row in inputfile:
kml.newpoint(name=row[0], coords=[(row[2], row[1])])
kml.save(file + '.kml')
When you use the context manager here:
with open(file, 'w') as f:
it reassigns to f, so when you try to access a value like f[x], it tries to call __getitem__(x) on f, which raises a TypeError
replace this block:
with open(file, 'w') as f:
wr = csv.writer(f)
wr.writerows(beamlist)
with something like:
with open(file, 'w') as fileobj:
wr = csv.writer(fileobj)
wr.writerows(beamlist)

How to fix “AttributeError: __enter__” when using csv.reader(open(..)..)?

I get the following error with my code:
Traceback (most recent call last):
File "C:\Users\XXX\Sentiment Analysis-vader.py", line 34, in <module>
f.printer()
File "C:\Users\XXX\Sentiment Analysis-vader.py", line 18, in printer
with csv.reader(open('analyse_' + str(bloombergcode) + '.csv', 'r'), delimiter= ",",quotechar='|') as q2:
AttributeError: __enter__
Process finished with exit code 1
I used the following code:
import csv
from nltk.sentiment.vader import SentimentIntensityAnalyzer
class VaderSentiment:
def __init__(self, bloomcode):
self.bloomcode = bloomcode
def print_sentiment_scores(self, sentence):
self.sentence = sentence
analyser = SentimentIntensityAnalyzer()
snt = analyser.polarity_scores(self.sentence)
print("{:-<40} {}".format(self.sentence, str(snt)))
def printer(self):
bloombergcode = self.bloomcode
with csv.reader(open('analyse_' + str(bloombergcode) + '.csv', 'r'), delimiter= ",",quotechar='|') as q2:
for line in q2:
for field in line:
print_sentiment_scores(field)
for code in ('AAPL', 'NFLX'):
f = VaderSentiment(code)
f.printer()
time.sleep(1)
I already saw some other similar problems (Python Json with returns AttributeError: __enter__) but the solutions do not work on my problem.
Does anyone see the problem?
You're not using csv.reader correctly. It does not support being placed inside a with statement.
Try to do it the same way as in the usage example:
with open('analyse_' + str(bloombergcode) + '.csv', 'r') as csv_file:
q2 = csv.reader(csv_file, delimiter=',', quotechar='|')
for line in q2:
# ..rest of your code..
Wrap open instead inside the with (because open supports it and is actually the recommended way of using it) then use csv.reader inside it.

CSV write error in Python

I have the following code:
def saveFile(self, master = None):
f = asksaveasfile(mode='w',defaultextension='.csv')
if f is None: # asksaveasfile returns `None` if dialog closed with "cancel".
return
f.close()
cords2save = globalCords # coordinates from another csv file
csvOpen = open(f, 'w')
w = csv.writer(fp)
w.writerow(cords2save)
When I run this I get:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Jem\AppData\Local\Programs\Python\Python35- 32\lib\tkinter\__init__.py", line 1550, in __call__
return self.func(*args)
File "C:\Users\Jem\Documents\bbk\1FINisd\LineSimplification.py", line 143, in saveFile
csvOpen = open(f, 'w')
TypeError: invalid file: <_io.TextIOWrapper name='C:/Users/Jem/Documents/bbk/1FINisd/ard.csv' mode='w' encoding='cp1252'>
I really am stuck as the other thread solutions don't work - what have I done wrong?
Thanks
f = asksaveasfile(mode='w',defaultextension='.csv')
asksaveasfile returns a file object. You then try to call open on that file object. But open doesn't expect a file, it expects a file name.
Try using asksaveasfilename instead.
def saveFile(self, master = None):
filename = asksaveasfilename(mode='w',defaultextension='.csv')
if not filename:
return
with open(filename, 'w') as file:
w = csv.writer(file)
w.writerow(globalCords)
Alternatively, continue to use asksaveasfile, but don't close the file, and don't try to open a new one.
def saveFile(self, master = None):
f = asksaveasfile(mode='w',defaultextension='.csv')
if not f:
return
w = csv.writer(f)
w.writerow(globalCords)
f.close()

How to open a csv file for reading purpose using mmap in python?

I want to open csv file for reading purpose. But I'm facing some exceptions regarding to that.
I'm using Python 2.7.
main.python-
if __name__ == "__main__":
f = open('input.csv','r+b')
m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
reader = csv.DictReader(iter(m.readline, ""))
for read in reader:
num = read['time']
print num
output-
Traceback (most recent call last):
File "/home/PycharmProjects/time_gap_Task/main.py", line 22, in <module>
for read in reader:
File "/usr/lib/python3.4/csv.py", line 109, in __next__
self.fieldnames
File "/usr/lib/python3.4/csv.py", line 96, in fieldnames
self._fieldnames = next(self.reader)
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
How to resolve this error? and how to open csv file using mmap and csv in good manner so code is working perfect?
I know you asked this a while ago, but I actually created a module for myself that does this, because I do a lot of work with large CSV files, and sometimes I need to convert them into dictionaries, based on a key. Below is the code I've been using. Please feel free to modify as needed.
def MmapCsvFileIntoDict(csvFilePath, skipHeader = True, transform = lambda row: row, keySelector = lambda o: o):
"""
Takes a CSV file path and uses mmap to open the file and return a dictionary of the contents keyed
on the results of the keySelector. The default key is the transformed object itself. Mmap is used because it is
a more efficient way to process large files.
The transform method is used to convert the line (converted into a list) into something else. Hence 'transform'.
If you don't pass it in, the transform returns the list itself.
"""
contents = {}
firstline = False
try:
with open(csvFilePath, "r+b") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0)
for line in iter(mm.readline, b''):
if firstline == False:
firstline = True
if skipHeader == True:
continue
row = ''
line = line.decode('utf-8')
line = line.strip()
row = next(csv.reader([line]), '')
if transform != None and callable(transform):
if row == None or row == '':
continue
value = transform(row)
else:
value = row
if callable(keySelector):
key = keySelector(value)
else:
key = keySelector
contents[key] = value
except IOError as ie:
PrintWithTs('Error decomposing the companies: {0}'.format(ie))
return {}
except:
raise
return contents
When you call this method, you have some options.
Assume you have a file that looks like:
Id, Name, PhoneNumber
1, Joe, 7175551212
2, Mary, 4125551212
3, Vince, 2155551212
4, Jane, 8145551212
The easiest way to call it is like this:
dict = MmapCsvFileIntoDict('/path/to/file.csv', keySelector = lambda row: row[0])
What you get back is a dict looking like this:
{ '1' : ['1', 'Joe', '7175551212'], '2' : ['2', 'Mary', '4125551212'] ...
One thing I like to do is create a class or a namedtuple to represent my data:
class CsvData:
def __init__(self, row):
self.Id = int(row[0])
self.Name = row[1].upper()
self.Phone = int(row[2])
And then when I call the method, I pass in a second lambda to transform each row in the file to an object I can work with:
dict = MmapCsvFileIntoDict('/path/to/file.csv', transform = lambda row: CsvData(row), keySelector = lambda o: o.Id)
What I get back that time looks like:
{ 1 : <object instance>, 2 : <object instance>...
I hope this helps! Best of luck
When open a file with the flag b like this:
f = open('input.csv','r+b')
You read the file as bytes and not as string.
So, try to change the flags to r:
f = open('input.csv','r')
if you just want to read data with specific columnes from csv file, just try:
import csv
with open('input.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print row['time']

Categories

Resources