problem with dictionaries within lists

Grant Hallam gupsmail at ihatespam.shaw.ca
Wed Sep 25 01:23:21 EDT 2002


the code attached opens a small wxPython frame with menu's to select parsing web survey entries or mailing list 
responses which are then outputted to Excel.  Problem occurs in the parsing part of the code.  After the last 
elif statement I have a list appended with a dictionary that is created my matching keys to the parsed text file. 
 However, the list seems to get populated with the same dictionary repeatedly until the entire file is parsed.  It
 is currently over 305 entries so the resulting list is 305 dictionaries holding the same value instead of unique
 entries.  Any help would be grateful,hopefully it is just a stupid error on my part :)

import string,re
from win32com.client import Dispatch
from wxPython.wx import *
#Global variables holding event ID's for menus
ID_Web = 101
ID_Mail = 102
ID_EXIT = 103
ID_ABOUT = 201
#Compiled regular expressions
#Used in web parser
rcN = re.compile('Name')
rcL = re.compile('Location')
rcT = re.compile('Transit')
rcTN = re.compile('Technical_Knowledge')
rcLS = re.compile('Like_Site')
rcRT = re.compile('Resolve_Tech_Issues')
rcEN = re.compile('Easy_Navigation')
rcPC = re.compile('Publish_Comments')
rcAN = re.compile('Answered_No')
rcFS = re.compile('Find_Support')
rcFSO = re.compile('Find_Support_Other')
rcFI = re.compile('Find_Information')
rcWLS = re.compile('Which_LEOnet_Site')
rcFIO = re.compile('Find_Information_Other')
rcVA = re.compile('Visit_Again')
rcVOS = re.compile('Visited_Old_Site')
rcTS = re.compile('Time_Spent')
rcRTI = re.compile('resolve_tech_issues')
#Used in both web and mail parser
rcP = re.compile('Position')
rcC = re.compile('Comments')
rcB = re.compile('B1')
#Used in mail parser
rcM = re.compile('Membership')
rcEM = re.compile('Email_address')

class MainFrame(wxFrame):
	'''Main window for program, uses menus to call parsing engines that output results to excel'''
	def __init__(self, parent, ID, title):
		wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(200, 150))
		#sets up status bar
		self.CreateStatusBar()
		self.SetStatusText("Version 3.1, built by Grant Hallam")
		#sets up file menu
		filemenu = wxMenu()
		filemenu.Append(ID_Web, "&Web Survey", "Go find your file")
		filemenu.Append(ID_Mail, "&Mail Survey", "Go find your file")
		filemenu.AppendSeparator()
		filemenu.Append(ID_EXIT, "&Exit", "Terminates the program")
		#sets up help menu
		helpmenu = wxMenu()
		helpmenu.Append(ID_ABOUT, "&About", "Info about program")
		#adds the menubar
		menuBar = wxMenuBar()
		menuBar.Append(filemenu, "&File")
		menuBar.Append(helpmenu, "Help")
		self.SetMenuBar(menuBar)
		#links events from menus to id and callable def's
		EVT_MENU(self, ID_Web, self.Web)
		EVT_MENU(self, ID_Mail, self.Mail)
		EVT_MENU(self, ID_EXIT, self.Exit)
		EVT_MENU(self, ID_ABOUT, self.About)
	def Web(self, event):
		'''Opens file dialog box to select web data file to parse'''
		dlg = wxFileDialog(self, "Choose a file", ".", "", "*.*", wxOPEN|wxMULTIPLE)
		if dlg.ShowModal() == wxID_OK:
			for path in dlg.GetPaths():
				filename = path
			parsefile = WebParser(filename)
		dlg.Destroy()
	def Mail(self, event):
		'''Opens file dialog box to select mail data file to parse'''
		dlg = wxFileDialog(self, "Choose a file", ".", "", "*.*", wxOPEN|wxMULTIPLE)
		if dlg.ShowModal() == wxID_OK:
			for path in dlg.GetPaths():
				filename = path
			parsefile = MailParser(filename)
		dlg.Destroy()		
	def Exit(self, event):
		'''Closes the program'''
		self.Close(true)
	def About(self, event):
		'''Opens the about dialog box'''
		dlg = wxMessageDialog(self, 'This program parses text files currently coded to parse\n survey & mail responses but future parsing engines\n may be included.', 'About Parsing', wxOK | wxICON_INFORMATION)   
		dlg.ShowModal()
		dlg.Destroy()
class MailParser:
	'''This class parses a text file containing mailing list entries, and outputs the results to excel'''
	def __init__(self, filename):
		'''Gets filename and calls the FileRead method'''
		self.filename = filename
		self.FileRead()
	def FileRead(self):
		'''Opens the text file, parses it, stores the various sections into a dictionary, and then stores that into a list, which is then iterated over to output result in to excel'''
		file = open(self.filename, 'r')
		input = file.read()
		file.close()
		#sets the column title dictionary, the field names dictionary, the pos list for the variable field values of Position, and the maildatabaselist that stores all the field dictionaries
		columntitle = ['Membership','Email_address','Position','Comments']
		dict = {'Membership':'','Email_address':'','Position':'','Comments':'','B1':''}
		pos = []
		maildatabaselist = []
		#This is the guts of the parser, splits the file into blocks,then splits the blocks in to lists of two fields, compares the 1st field to a RE, and adds the 2nd field to the field name dict	
		rawline = string.split(input, '\n')
		for x in rawline:	
			list = string.split(x, '=')
			if rcM.match(list[0]): 
				case = string.capwords(list[1])
				dict['Membership'] = case
			elif rcEM.match(list[0]): 
				dict['Email_address'] = list[1]
			elif rcP.match(list[0]): 
				pos.append(list[1])
			elif rcC.match(list[0]): 
				dict['Comments'] = list[1]
			elif rcB.match(list[0]): 
				dict['B1'] = list[1]
				#joins the various items in pos list into one string that is inserted in the Position field, 
				POS = string.join(pos,',')
				dict['Position'] = POS
				#adds field name dict to maildatabaselist
				maildatabaselist.append(dict)
				fs = []
				fi = []
		#opens Excel, sets to visible, and adds a worksheet
		xlApp = Dispatch('Excel.Application')
		xlApp.Visible = 1
		workbook = xlApp.Workbooks.Add()
		worksheet = workbook.Worksheets.Add()
		#sets the titles of the columns
		count = 0
		for x in columntitle:
			cell = columntitle[count]
			count = count+1
			worksheet.Cells(1,count).Font.Bold=1
			worksheet.Cells(1,count).Value = cell
		#sets up excel cells and inserts maildatabaselist fields into cells
		row = 2
		for x in maildatabaselist:
			row = row +1
			worksheet.Cells(row,1).Value = x['Membership']
			worksheet.Cells(row,2).Value = x['Email_address']
			worksheet.Cells(row,3).Value = x['Position']
			worksheet.Cells(row,4).Value = x['Comments']
		#adds bottom column headers to excel
		count = 0
		titlerow = row +2
		for x in columntitle:
			cell = columntitle[count]
			count = count+1
			worksheet.Cells(titlerow,count).Font.Bold=1
			worksheet.Cells(titlerow,count).Value = cell
class WebParser:
	'''This class parses a text file containing web survey list entries, and outputs the results to excel'''
	def __init__(self, filename):
		'''Gets filename and calls the FileRead method'''
		self.filename = filename
		self.FileRead()
	def FileRead(self):
		'''Opens the text file, parses it, stores the various sections into a dictionary, and then stores that into a list, which is then iterated over to output result in to excel'''
		file = open(self.filename, 'r')
		input = file.read()
		file.close()
		#sets the column title dictionary, the field names dictionary, the fs and fi list for the variable field values of Find support and find information, and the webdatabaselist that stores all the field dictionaries
		columntitle = ['Name','Transit','Location','Position','Knowledge','Like site','Resolve issues','Navigate','Publish','Answer no','Find support','Find support other','Find information','Find information other','Which leonet other','Visit','Old visit','Spent','Comments']
		dict = {'Name': '','Location':'','Transit':'','Position':'','Technical_Knowledge':'','Like_Site':'','Resolve_Tech_Issues':'','Easy_Navigation':'','Publish_Comments':'','Answered_No':'','Find_Support':'','Find_Support_Other':'','Find_Information':'','Which_LEOnet_Site':'','Find_Information_Other':'','Visit_Again':'','Visited_Old_Site':'','Time_Spent':'','Comments':'','B1':''}
		fs = []
		fi = []
		webdatabaselist = []
		#This is the guts of the parser, splits the file into blocks,then splits the blocks in to lists of two fields, compares the 1st field to a RE, and adds the 2nd field to the field name dict	
		rawline = string.split(input, '\n')
		for x in rawline:	
			list = string.split(x, '=')
			if rcN.match(list[0]): 
				case = string.capwords(list[1])
				dict['Name'] = case
			elif rcL.match(list[0]): 
				dict['Location'] = list[1]
			elif rcT.match(list[0]): 
				dict['Transit'] = list[1]
			elif rcP.match(list[0]): 
				dict['Position'] = list[1]
			elif rcTN.match(list[0]): 
				dict['Technical_Knowledge'] = list[1]
			elif rcLS.match(list[0]): 
				dict['Like_Site'] = list[1]
			elif rcRT.match(list[0]): 
				dict['Resolve_Tech_Issues'] = list[1]
			elif rcEN.match(list[0]): 
				dict['Easy_Navigation'] = list[1]	
			elif rcPC.match(list[0]): 
				dict['Publish_Comments'] = list[1]
			elif rcAN.match(list[0]): 
				dict['Answered_No'] = list[1]
			elif rcFIO.match(list[0]): 
				dict['Find_Information_Other'] = list[1]
			elif rcWLS.match(list[0]): 
				dict['Which_LEOnet_Site'] = list[1]
			elif rcFSO.match(list[0]):
				dict['Find_Support_Other'] = list[1]
			elif rcFS.match(list[0]): 
				fs.append(list[1])
			elif rcFI.match(list[0]): 
				fi.append(list[1])
			elif rcVA.match(list[0]): 
				dict['Visit_Again'] = list[1]
			elif rcVOS.match(list[0]): 
				dict['Visited_Old_Site'] = list[1]
			elif rcTS.match(list[0]): 
				dict['Time_Spent'] = list[1]
			elif rcC.match(list[0]): 
				dict['Comments'] = list[1]
			elif rcB.match(list[0]): 
				dict['B1'] = list[1]
				#joins the various items in fs and fi list into one string that is inserted in the Find Support and Find Information fields,
				findS = string.join(fs,',')
				dict['Find_Support'] = findS
				findI = string.join(fi,',')
				dict['Find_Information'] = findI
				#print dict
				#adds field name dict to maildatabaselist
				webdatabaselist.append(dict)
				fs = []
				fi = []
	
		totalnumberrecords = len(webdatabaselist)
		#opens Excel, sets to visible, and adds a worksheet		
		xlApp = Dispatch('Excel.Application')
		xlApp.Visible = 1
		workbook = xlApp.Workbooks.Add()
		worksheet = workbook.Worksheets.Add()
		#sets the titles of the columns
		count = 0
		for x in columntitle:
			cell = columntitle[count]
			count = count+1
			worksheet.Cells(1,count).Font.Bold=1
			worksheet.Cells(1,count).Value = cell
		#sets up excel cells and inserts webdatabaselist fields into cells
		row = 2
		for x in webdatabaselist:
			row += 1
			worksheet.Cells(row,1).Value = x['Name']
			worksheet.Cells(row,2).Value =x['Transit']
			worksheet.Cells(row,3).Value =x['Location']
			worksheet.Cells(row,4).Value =x['Position']
			worksheet.Cells(row,5).Value =x['Technical_Knowledge']
			worksheet.Cells(row,6).Value =x['Like_Site']
			worksheet.Cells(row,7).Value =x['Resolve_Tech_Issues']
			worksheet.Cells(row,8).Value =x['Easy_Navigation']
			worksheet.Cells(row,9).Value =x['Publish_Comments']
			worksheet.Cells(row,10).Value =x['Answered_No']
			worksheet.Cells(row,11).Value =x['Find_Support']
			worksheet.Cells(row,12).Value =x['Find_Support_Other']
			worksheet.Cells(row,13).Value =x['Find_Information']		
			worksheet.Cells(row,14).Value =x['Find_Information_Other']
			worksheet.Cells(row,15).Value =x['Which_LEOnet_Site']
			worksheet.Cells(row,16).Value =x['Visit_Again']
			worksheet.Cells(row,17).Value =x['Visited_Old_Site']
			worksheet.Cells(row,18).Value =x['Time_Spent']
			worksheet.Cells(row,19).Value =x['Comments']

		#adds bottom column headers to excel
		count = 0
		titlerow = row +2
		for x in columntitle:
			cell = columntitle[count]
			count = count+1
			worksheet.Cells(titlerow,count).Font.Bold=1
			worksheet.Cells(titlerow,count).Value = cell
class SurveyParser(wxApp):
	def OnInit(self):
		frame = MainFrame(NULL, -1, "SurveyParser")
		frame.Show(true)
		self.SetTopWindow(frame)
		return true
app = SurveyParser(0)
app.MainLoop()


Sample text file for web parser
Name = Mourad Salji
Location = Western Canada
Transit = 05110
Position = Other
Technical_Knowledge = Expert
Like_Site = Yes
Resolve_Tech_Issues = Yes
Easy_Navigation = Yes
Found_Everything = Yes
Publish_Comments = Yes
Answered_No = 
Find_Support = TSC_Telephone
Find_Support = TSC_Web
Find_Support_Other = (Other - describe here)
Find_Information = TSC_Telephone
Find_Information = Word_Of_Mouth
Which_LEOnet_Site = (Which LEOnet site?)
Find_Information_Other = (Other - describe here)
Visit_Again = Daily
Visited_Old_Site = When_A_Problem_Occurs
Time_Spent = 5_Plus_Minutes
Comments = 
B1 = Submit

Name = Nelson
Location = Eastern Canada
Transit = 08271
Position = Other
Technical_Knowledge = Expert
Like_Site = Yes
Resolve_Tech_Issues = Yes
Easy_Navigation = Yes
Found_Everything = Yes
Publish_Comments = Yes
Answered_No = 
Find_Support = TSC_Telephone
Find_Support_Other = (Other - describe here)
Find_Information = TSC_Telephone
Which_LEOnet_Site = (Which LEOnet site?)
Find_Information_Other = (Other - describe here)
Visit_Again = When_A_Problem_Occurs
Visited_Old_Site = Never
Time_Spent = 5_Plus_Minutes
Comments = great JOB
B1 = Submit

Name = Dina Della Porta
Location = Eastern Canada
Transit = 03511
Position = Other
Technical_Knowledge = Expert
Like_Site = Yes
Resolve_Tech_Issues = Yes
Easy_Navigation = Yes
Found_Everything = Yes
Publish_Comments = Yes
Answered_No = 
Find_Support = Other
Find_Support_Other = My own department
Find_Information = Other
Which_LEOnet_Site = (Which LEOnet site?)
Find_Information_Other = surfing
Visit_Again = When_A_Problem_Occurs
Visited_Old_Site = Never
Time_Spent = Less_Than_2_Minutes
Comments = The site came in handy for a SECAF problem I was working on.  
B1 = Submit

Name = MARYKE GAUVREAU
Location = Western Canada
Transit = 00620
Position = Branch - Other
Technical_Knowledge = Average
Like_Site = Yes
Resolve_Tech_Issues = Yes
Easy_Navigation = Yes
Found_Everything = Yes
Publish_Comments = Yes
Answered_No = 
Find_Support = TSC_Telephone
Find_Support = Word_Of_Mouth
Find_Support = TSC_Web
Find_Support = LEOnet
Find_Support = Folio_HOCircular
Find_Support_Other = (Other - describe here)
Find_Information = TSC_Newsletter
Which_LEOnet_Site = (Which LEOnet site?)
Find_Information_Other = (Other - describe here)
Visit_Again = When_A_Problem_Occurs
Visited_Old_Site = When_A_Problem_Occurs
Time_Spent = 5_Plus_Minutes
Comments = 
B1 = Submit



More information about the Python-list mailing list