Create an interactive command loop using inheritance python34 - python
I'm trying to see how I can structure a script in a way that I can use the inheritance method. I'm fairly new to python. And my problem is using variables in one class from another class-def. I just recently learned about the super function and I don't think I'm using it right because it keeps printing and recalculating everything that it's pulling from.
Let's say I have a bunch of messages coming in a text file delimited by commas that give me different information. I want to be able to take that text file and...
be able to read the content delimited by commas (done)
tell me how many of each type of message there are (done)
then create a class called messages that has defs for each type of message with its respective calculations and variables it creates in those instances (done)
create class to print and write those calculations and variables in the client and xls (partially done due to my issue)
create class to convert xls to csv and kml (somewhat done)
Here is a toy structure of what I'm working with
import bunch of stuff
data = [] #empty because we will store data into it
#Reads a CSV file and return it as a list of rows
def read_csv_file(filename):
"""Reads a CSV file and return it as a list of rows."""
for row in csv.reader(open(filename)):
data.append(row)
return data
with open(path_in + data_file) as csvfile:
read_it = list(csv.reader(csvfile, delimiter=','))
#Counts the number of times a GPS command is observed
def list_msg_type_countdata):
"""Counts the number of times a GPS command is observed.
Returns a dictionary object."""
msg_count = dict()
for row in data:
try:
msg_count[row[0]] += 1
except KeyError:
msg_count[row[0]] = 1
return msg_count
print(list_msg_type_count(read_it))
print ("- - - - - - - - - - - - -")
class CreateWorkbook:
def openworkbook(self, data):
global output_filename
output_filename = input('output filename:')
global workbook
workbook = xlsxwriter.Workbook(path_out + output_filename + '_' + command_type +'.xlsx')
self.worksheet = workbook.add_worksheet()
#formatting definitions
global bold
bold = workbook.add_format({'bold': True})
global date_format
date_format = workbook.add_format({'num_format': "m/d/yyyy hh:mm:ss"})
global time_format
time_format = workbook.add_format({'num_format': "hh:mm:ss"})
def closeworkbook_gprmc(self, data):
print('closeworkbook')
#pull data from process_msg1
(i1, i2, i3) = messagetype.process_msg1(data)
#sets up the header row
self.worksheet.write('A1','item1',bold)
self.worksheet.write('B1', 'item2',bold)
self.worksheet.write('C1', 'item3',bold)
self.worksheet.autofilter('A1:C1') #dropdown menu created for filtering
# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(data, start=1): #where you want to start printing results inside workbook
for c, col in enumerate(data):
self.worksheet.write_column(r,0, i1)
self.worksheet.write_column(r,1, i2)
self.worksheet.write_column(r,2, i3)
workbook.close()
f.close()
print('XLSX file named ' + output_filename + '_' + command_type +' was created')
def closeworkbook_msg2(self, data):
#pull data from process_msg2
(i1, i2, i3, i4) = messagetype.process_msg2(data)
#sets up the header row
self.worksheet.write('A1','item1',bold)
self.worksheet.write('B1', 'item2',bold)
self.worksheet.write('C1', 'item3',bold)
self.worksheet.write('C1', 'item4',bold)
self.worksheet.autofilter('A1:C1') #dropdown menu created for filtering
# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(data, start=1): #where you want to start printing results inside workbook
for c, col in enumerate(data):
self.worksheet.write_column(r,0, i1)
self.worksheet.write_column(r,1, i2)
self.worksheet.write_column(r,2, i3)
self.worksheet.write_column(r,3, i4)
workbook.close()
f.close()
print('XLSX file named ' + output_filename + '_' + command_type + ' was created')
class ConvertFile
def convert2csv(self, data):
# set path to folder containing xlsx files
os.chdir(path_out)
# find the file with extension .xlsx
xlsx = glob.glob(output_filename + '_' + command_type + '.xlsx')
# create output filenames with extension .csv
csvs = [x.replace('.xlsx','.csv') for x in xlsx]
# zip into a list of tuples
in_out = zip(xlsx,csvs)
# loop through each file, calling the in2csv utility from subprocess
for xl,csv in in_out:
out = open(csv,'w')
command = 'c:/python34/scripts/in2csv %s\\%s' % (path_out,xl)
proc = subprocess.Popen(command,stdout=out)
proc.wait()
out.close()
print('CSV file named ' + output_filename + '_' + command_type + ' was created')
def convert2kml(self, data):
#Input the file name.
h = open(path_out + output_filename + '_' + command_type + '.csv')
with h as csvfile2:
data2 = csv.reader(csvfile2,delimiter=',')
next(data2)
#Open the file to be written.
g = open(output_filename + '_' + command_type +'.kml','w')
g.write("<?xml version='1.0' encoding='UTF-8'?>\n")
g.write("<kml xmlns='http://earth.google.com/kml/2.1'>\n")
g.write("<Document>\n")
g.write(" <name>" + output_filename + '_' + command_type + '.kml' +"</name>\n")
for row in data2:
g.write(" <Placemark>\n")
g.write("<TimeStamp><when>" + str(row[0]) + "</when></TimeStamp>\n")
g.write(" <Point>\n")
g.write(" <coordinates>" + str(row[2]) + "," + str(row[1]) + "</coordinates>\n")
g.write(" </Point>\n")
g.write(" </Placemark>\n")
g.write("</Document>\n")
g.write("</kml>\n")
g.close()
h.close()
print('and ' + output_filename + '_' + command_type +'.kml was created,too!')
class MessageType:
def process_msg1(self,data)
item1 = []
item2 = []
item3 = []
print('printing stuff')
for r in data:
if row[0] == 'msg type1'
item1.append('calculations')
item2.append('calculations')
item3.append('calculations')
print('calculations done')
return(array(item1),array(item2),array(item3))
def process_msg2(self,data)
item1 = []
item2 = []
item3 = []
item4 = []
print('printing stuff')
for r in data:
if row[0] == 'msg type1'
item1.append('calculations')
item2.append('calculations')
item3.append('calculations')
item4.append('calculations')
print('calculations done')
return(array(item1),array(item2),array(item3),array(item4))
class PrintMSG(MessageType):
def process_msg1(self, data):
(i1, i2, i3) = super(PrintMSG, self).process_msg1(data)
print('printing plus plotting using variables from class Message')
def process_msg2(self, data):
(i1, i2, i3,i4) = super(PrintMSG, self).process_msg2(data)
print('printing plus plotting using variables from class Message')
#processing piece
keep_asking = True
while keep_asking:
command_type = input("What message type do you want to look at?")
if command_type == 'msg type1':
createworkbook = CreateWorkbook()
createworkbook.openworkbook(data)
msg = MessageType()
print_msg = PrintMSG()
print_msg.process_msg1(data)
createworkbook.closeworkbook_msg1(data)
convert2csv(data)
convert2kml(data)
elif command_type == 'msg type2':
createworkbook = CreateWorkbook()
createworkbook.openworkbook(data)
msg = MessageType()
print_msg = PrintMSG()
print_msg.process_msg2(data)
createworkbook.closeworkbook_msg2(data)
convert2csv(data)
convert2kml(data)
else:
print("Invalid type:", command_type)
wannalook = input('Want to look at another message or no?')
if not wannalook.startswith('y'):
keep_asking = False
Class definition
The code is kind of big and there are many things that do not work or could be improved. As a starter, take the class CreateWorkbook. You need always use self, as the first argument for methods. (There are a few exceptions but they are not relevant here.) To be able to use variables defined in one method in another, you need to prefix them with self.:
class CreateWorkbook:
def openworkbook(self, data):
self.output_filename = input('output filename:')
self.workbook = xlsxwriter.Workbook(path_out + output_filename + '_' + command_type +'.xlsx')
self.worksheet = workbook.add_worksheet()
def closeworkbook_msg1(self, data):
#sets up the header row
self.worksheet.write('A1','item1',bold)
self.worksheet.write('B1', 'item2',bold)
self.worksheet.write('C1', 'item3',bold)
self.worksheet.autofilter('A1:C1') #dropdown menu created for filtering
# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(data, start=1): #where you want to start printing results inside workbook
for c, col in enumerate(data):
self.worksheet.write_column(r,0, i1)
self.worksheet.write_column(r,1, i2)
self.worksheet.write_column(r,2, i3)
self.workbook.close()
print('XLSX file named ' + output_filename + '_' + command_type +' was created')
def closeworkbook_msg2(self, data):
#sets up the header row
self.worksheet.write('A1','item1',bold)
self.worksheet.write('B1', 'item2',bold)
self.worksheet.write('C1', 'item3',bold)
self.worksheet.write('C1', 'item4',bold)
self.worksheet.autofilter('A1:C1') #dropdown menu created for filtering
# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(data, start=1): #where you want to start printing results inside workbook
for c, col in enumerate(data):
self.worksheet.write_column(r,0, i1)
self.worksheet.write_column(r,1, i2)
self.worksheet.write_column(r,2, i3)
self.worksheet.write_column(r,3, i4)
self.workbook.close()
print('XLSX file named ' + output_filename + '_' + command_type + ' was created')
Reading csv
This doesn't make much sense:
f = open(path_in + data_file)
read_it = read_csv_file(path_in + data_file)
with f as csvfile:
readCSV = csv.reader(csvfile,delimiter=',')
I would interpret it as something like this:
with open(path_in + data_file) as csvfile:
read_it = list(csv.reader(csvfile, delimiter=','))
Related
Create two different xml files from single csv file using python
I am pretty new to python and I have one csv file and based on one condition I need to create two different xml files. The condition based on which I need to create two xml is as follows: If Primary spindle == 1 then data related to it will go to xml1 else xml2. This is how my xml looks like as shown in image: The code I am writing is as follows: import csv file = open(r'C:\Users\hu170f\MultiSpindleArchitechture\New folder\MAAP-S12_LH_UP_PASS-LN1-V1.csv') csvreader = csv.reader(file) xmlFile = r'C:\Users\hu170f\Documents\TEST\myData4.xml' xmlFile1 = r'C:\Users\hu170f\Documents\TEST\myData5.xml' #header = next(csvreader) xmlData = open(xmlFile, 'w') xmlData.write('<?xml version="1.0" encoding = "UTF-8"?>' + "\n") # there must be only one top-level tag xmlData.write('<MCD>' + "\n") xmlData1 = open(xmlFile1, 'w') xmlData1.write('<?xml version="1.0" encoding = "UTF-8"?>' + "\n") # there must be only one top-level tag xmlData1.write('<MCD>' + "\n") #print(header) rows = [] for row in csvreader: rows.append(row) #print(len(rows)) #print(len(row)) Field = " " Value = " " counter = 0 for i in rows: tag = i #print(tag) #print(len(rows)) for j in range(len(tag)): tag[j] = tag[j].replace(' ', '_') if j == 0: #print("Field = ", tag[j]) Field = tag[j] counter = counter +1 else: #print("Value = ", tag[j]) Value = tag[j] if(counter%2 == 0): xmlData.write(' ' + '<' + Field + '>' \ + Value + '</' + Field + '>' + "\n") else : xmlData1.write(' ' + '<' + Field + '>' \ + Value + '</' + Field + '>' + "\n") xmlData.write('</MCD>' + "\n") xmlData.close() xmlData1.write('</MCD>' + "\n") xmlData1.close() #print(rows[6]) file.close() I want both xml to contain common data from Header to LN and then data from WorkStep UUID till secondary Spindle based on the condition in each xml file.
How to fix errors IndexError: list index out of range
I would like load data which are 10 categories of document, each cateory contains text files, but I keep getting the following error: IndexError: list index out of range THis is code : def load_data(folder): data = [] files = [join(folder, x) for x in os.listdir(folder)] for file in files: topic = file.split("/")[9] # this is where the error occurs label = topic.replace(" ", "_") name = "__label__" + label with open(file, "rb") as f: content = f.read() content = content.decode('utf-16') content = " ".join(i for i in content.split()) data.append(name + " " + content) return data
Easy way to debug this would be to add print statements and check what the objects hold. For e.g. in this case, you can add 2 print statements at the beginning of the for loop. This would help you to figure out why you are getting IndexError def load_data(folder): data = [] files = [join(folder, x) for x in os.listdir(folder)] for file in files: print(file) print(file.split("/")) topic = file.split("/")[9] # this is where the error occurs label = topic.replace(" ", "_") name = "__label__" + label with open(file, "rb") as f: content = f.read() content = content.decode('utf-16') content = " ".join(i for i in content.split()) data.append(name + " " + content) return data
There's no value in my output file
my file contains "Name" and 5 eye movement values (TFF, TFD, TVD, FB, FC). I want to sum up each eye movement values if the rows under Name column are the same. It seems like the code is working, there's no error happened, but my output files stayed empty. Could anyone give me some pointers where went wrong? Here's the code: import csv file = open("P01_All.csv", "r") #Open CSV File in Read Mode reader = csv.reader(file) #Create reader object which iterates over lines outfile = open("Name.csv","w") outfile2 = open("TFF.csv","w") outfile3 = open("TFD.csv","w") outfile4 = open("TVD.csv","w") outfile5 = open("FB.csv","w") outfile6 = open("FC.csv","w") class Object: #Object to store unique data def __init__(self, Name, TFF, TFD, TVD, FB, FC): self.Name = Name self.TFF = TFF self.TFD = TFD self.TVD = TVD self.FB = FB self.FC = FC rownum = 0 #Row Number currently iterating over list = [] #List to store objects def checkList(Name, TFF, TFD, TVD, FB, FC): for object in list: #Iterate through list if object.Name == Name: object.TFF += float(TFF) object.TFD += float(TFD) object.TVD += float(TVD) object.FB += float(FB) object.FC += float(FC) return newObject = Object(Name, float(TFF),float(TFD), float(TVD), float(FB), float(FC)) #Create a new object with new eye and TFF list.append(newObject) #Add to list and break out for row in reader: #Iterate through all the rows if rownum == 0: #Store header row seperately to not get confused header = row else: Name = row[0] TFF = row[1] TFD = row[2] TVD = row[3] FB = row[4] FC = row[5] if len(list) == 0: #Default case if list = 0 newObject = Object(Name, float(TFF),float(TFD), float(TVD), float(FB), float(FC)) list.append(newObject) else: #If not... checkList(Name, TFF, TFD, TVD, FB, FC) rownum += 1 for each in list: #Print out result # print(each.Name, each.TFF, each.TFD, each.TVD, each.FB, each.FC) outfile.write(each.Name + "\n" ) outfile2.write(str(each.TFF)+ "\n" ) outfile3.write(str(each.TFD)+ "\n" ) outfile4.write(str(each.TVD)+ "\n" ) outfile5.write(str(each.FB)+ "\n" ) outfile6.write(str(each.FC)+ "\n" ) file.close() #Close file outfile.close() outfile2.close() outfile3.close() outfile4.close() outfile5.close() outfile6.close()
Like #zwer said, the reason why you have nothing in your output file is because you don't increment rownum while you are iterating the rows from your input file. By indenting the line rownum += 1 you put it inside your loop where you read each row. So with minimal modification it would look import csv file = open("P01_All.csv", "r") #Open CSV File in Read Mode reader = csv.reader(file) #Create reader object which iterates over lines outfile = open("Name.csv","w") outfile2 = open("TFF.csv","w") outfile3 = open("TFD.csv","w") outfile4 = open("TVD.csv","w") outfile5 = open("FB.csv","w") outfile6 = open("FC.csv","w") class Movement_value: #Object to store unique data def __init__(self, Name, TFF, TFD, TVD, FB, FC): self.Name = Name self.TFF = TFF self.TFD = TFD self.TVD = TVD self.FB = FB self.FC = FC rownum = 0 #Row Number currently iterating over notebook = [] #List to store objects def checkList(Name, TFF, TFD, TVD, FB, FC): for value in notebook: #Iterate through list if value.Name == Name: value.TFF += float(TFF) value.TFD += float(TFD) value.TVD += float(TVD) value.FB += float(FB) value.FC += float(FC) return newObject = Movement_value(Name, float(TFF),float(TFD), float(TVD), float(FB), float(FC)) #Create a new object with new eye and TFF notebook.append(newObject) #Add to list and break out for row in reader: #Iterate through all the rows if rownum == 0: #Store header row seperately to not get confused header = row else: Name = row[0] TFF = row[1] TFD = row[2] TVD = row[3] FB = row[4] FC = row[5] if len(notebook) == 0: #Default case if list = 0 newObject = Movement_value(Name, float(TFF),float(TFD), float(TVD), float(FB), float(FC)) notebook.append(newObject) else: #If not... checkList(Name, TFF, TFD, TVD, FB, FC) rownum += 1 for each in notebook: #Print out result # print(each.Name, each.TFF, each.TFD, each.TVD, each.FB, each.FC) outfile.write(each.Name + "\n" ) outfile2.write(str(each.TFF)+ "\n" ) outfile3.write(str(each.TFD)+ "\n" ) outfile4.write(str(each.TVD)+ "\n" ) outfile5.write(str(each.FB)+ "\n" ) outfile6.write(str(each.FC)+ "\n" ) file.close() #Close file outfile.close() outfile2.close() outfile3.close() outfile4.close() outfile5.close() outfile6.close() I have made some additional change: It's better that you don't use list or object as variable names because they are already used in Python and by doing so you'll override their meaning. You could have a bad surprise eventually. But we can do more. We don't need to create a class to hold the values We can work with files using context managers to make sure that our file is not kept open for not relevant reasons. Here's a version that is shorter than yours: import csv import pathlib input_filepath = pathlib.Path("Input.csv") output_filepath = pathlib.Path("") with open(input_filepath, newline="") as input_file: # Where our data will be kept input_data = {} csv_reader = csv.reader(input_file) # Skip the first line next(csv_reader) for (Name, *rest_of_data) in csv_reader: if Name in input_data: for (index_of_data_to_update, data_to_update) in enumerate(rest_of_data): input_data[Name][index_of_data_to_update] += float(data_to_update) else: input_data[Name] = [float(x) for x in rest_of_data] output_rows = ([name] + list(data) for (name, data) in input_data.items()) output_filenames = [ "Name.csv", "TFF.csv", "TFD.csv", "TVD.csv", "FB.csv", "FC.csv" ] output_files = [open(output_filepath / filename, "w") for filename in output_filenames] # Open all the files with output_files[0], output_files[1], output_files[2], output_files[3], \ output_files[4], output_files[5]: for row in output_rows: for (output_file, data) in zip(output_files, row): output_file.write("{}\n".format(data))
Python, write tuple into binary file
I'm trying to write tuple ('hola', 'cheese', '1235265'), ('hey', 'weird', '30193') getting from mysql DB, putting values into binary file I saw it got DB table as tuple. Tried to convert into binary, didn't work well. So i tried another with tuple -> string -> binary, still has an error... is there any good ways to write tuple to binary file in Python? for i in text_query: query = "select * from " + i curs.execute(query) # Data Fetch from Mysql rows = curs.fetchall() results = [".".join(map(str, r)) for r in rows] make_file(name,i,results) conn.close() def make_file(name, filename, rows): if filename == 'student': with open(name + '_' + filename + '.dat', 'wb') as fp: for i in rows: fp.write(bytearray(rows + '\n')) elif filename == 'course': with open(name + '_' + filename + '.dat', 'wb') as fp: for i in rows: fp.write(bytearray(rows + '\n')) elif filename == 'course_taken': with open(name + '_' + filename + '.dat', 'wb') as fp: for i in rows: fp.write(bytearray(rows + '\n')) else: return 0;
You can write a binary representation of your data to file easily enough, not that it would be a good idea, from an encoding point of view. Nor will it be easy to read back in, but this will work: def make_text_file(name, filename, rows): if filename == 'student': # with open(name + '_' + filename + '.txt', 'w') as fp: row_index = 0 fp.write('<record start>') for i in rows: row_index += 1 fp.write('<row {0}>{1}</row>'.format(row_index, i)) fp.write('<record end>\n') def make_binary_file(name, filename, rows): if filename == 'student': with open(name + '_' + filename + '.dat', 'wb') as fp: row_index = 0 for i in rows: row_index += 1 fp.write(bytes((i), 'utf8')) def test_things(): """ Generate some data to write to file """ rows = ('hola', 'cheese', '1235265') #make_file('student', 'test_student.txt', rows) make_text_file('test', 'student', rows) rows = ('hey', 'weird', '30193') make_binary_file('test', 'student', rows) if __name__ == '__main__': test_things()
Data Jumbeling in csv file
I have application in PyQt. On submit, All the combobox and line edit and qplaintextedit and the info from qtable widget are added into a list. The list pastes data into csv file and refreshes the fields that are present. And new information gets loaded into qtablewidget area. Next again information from all the fields below+qtablewidget information is added into csv file. But, the information in csv files are getting jumbled. qtablewidget information must have information of fields which are given below. But it gets interchanged. Any Suggestions ? if os.path.isfile("Rts.csv") is True: with open('Rts.csv', 'r') as fo: reader = csv.reader(fo, delimiter = ',') ncol = len(next(reader)) data = list(reader) row_count = len(data) if staticVariable.static_count_clicked <= row_count: print staticVariable.static_count_clicked main = data[staticVariable.static_count_clicked] print main data = [] xdata = [str(da), str(compout), str(locout), str(resout), str(geotxt), str(landtxt), str(suggestxt), str(remarkstxt)] data = [main + xdata] print data if os.path.isfile("rts_output.csv") is True: with open('rts_output.csv', 'a') as fp: a = csv.writer(fp, delimiter = ',' ) awrite = a.writerows(data) fp.close() for var in range(0, ncol): self.dadis.setItem(0, var, QTableWidgetItem(main[var])) pbvar = staticVariable.static_count_clicked print pbvar self.no_cases.setText(str(pbvar) + " Cases done out of - " + str(row_count)) staticVariable.static_count_clicked += 1 staticVariable.static_main_clicked += 1 fp.close()