Select to view content in your preferred language

Problem Updating Dictionary when parsing a CSV file

1308
4
08-29-2010 06:25 PM
DarcyGuyant
New Contributor
I can't figure out how to update the Array associated with a Key in the Dictionary.

I don't have a problem parsing the CSV file; each line has a Rhino Name (which will be the key in the Dictionary) and associated X & Y values.  I am also able to created the Dictionary with the Rhino Name as Key as associate an Array with each Key. 

The problem is when I try to ".add" the new point to the Array all the Arrays get overwritten with the new Added point. At the end I have 5 Key:Array associations but the Array are all the same points/tracks.

As each line of the CSV file is read how do I add the new point to the Array in the dictionary associated with that specific Key, without messing up the Arrays/Points in the other Arrays? 

The output will be to a feature class which has already been created.  The feature class will show "tracks" of five different Rhinos.  Right now all five of my records end up with all the same polylines, but they should all be different, consisting only of the a associated points for each Rhino.

Here is a portion of the CSV file I'm working with:

Observer,X,Y,Rhino,Comments
Ben,26.99391,-19.10447,Bo,
Ben,27.00071,-19.1089,Tulip,Bathing
Ben,26.9919,-19.10511,Bo,
Ben,27.00071,-19.1059,Tulip,
Ben,26.96809,-19.09578,Patches,
Ben,26.97808,-19.11016,Dinky,
Ben,26.99213,-19.10395,Bo,
Ben,27.00083,-19.10326,Tulip,

    # Open CSV file containing Rhino track points
    trackPointsPath = "C:\wcgis\GEOG485\Project_4\RhinoObservations.csv"
    trackPoints = open(trackPointsPath, "r")

    # Read first line of CSV file, strip "new line" and make Python List of Header titles
    headerLine = trackPoints.readline()
    headerLine = headerLine.rstrip("\n") 
    splitHeaderLine = headerLine.split(",")

    # Get index for needed Header fields
    indexPointX = splitHeaderLine.index("X")
    indexPointY = splitHeaderLine.index("Y")
    indexRhinoName = splitHeaderLine.index("Rhino")

    # Create an empty dictionary. Each key will be Rhino Name & values points Array.   
    dictionaryRhinoTracks = {}

    # Loop through each line in the CSV file & split with delimiter ","    
    for line in trackPoints.readlines():
        line = line.rstrip("\n")
        splitLine = line.split(",")
        print splitLine

        # Create variable for needed field items based on index position        
        pointX = splitLine[indexPointX]
        pointY = splitLine[indexPointY]
        rhinoName = splitLine[indexRhinoName]

        # Create a Point object         
        currentPoint = gp.createobject("Point")
        currentPoint.X = pointX
        currentPoint.Y = pointY

        # Check if the Dictionary contains Name, if yes pass, else createobject Array and add to the dictionary
        if rhinoName in dictionaryRhinoTracks:
            pass
        else:
            rhinoTrackArray = gp.createobject("Array")
            dictionaryRhinoTracks[rhinoName] = rhinoTrackArray

        # Check Keys in Dictionary and add Point Object (X & Y coordinates) to the Array       
        for key in dictionaryRhinoTracks:
            if key == rhinoName:            
                rhinoTrackArray.Add(currentPoint)]

    cursor = gp.InsertCursor(featureClassName)
    row = cursor.NewRow()
    for rhinoName in dictionaryRhinoTracks:
        row.Shape = rhinoTrackArray
        row.Rhino_Name = rhinoName
        cursor.InsertRow(row)


Thank you for any guidance.
Darcy
0 Kudos
4 Replies
Luke_Pinner
MVP Regular Contributor
Can you repost your script and wrap [noparse]
[/noparse] tags around your code so your indentation is preserved and we can easily see what your script is doing. I can't work out if loops are nested or not without the indentation.
					
				
			
			
				
			
			
				
			
			
			
			
			
			
		
0 Kudos
DarcyGuyant
New Contributor
Reposed with CODE tags.
0 Kudos
Luke_Pinner
MVP Regular Contributor
Your problem is you are never actually using the dictionary except to initially add the array, you are reusing of the "rhinoTrackArray" object instead of the dictionary array...

Try something like this:

        # Check if the Dictionary does not contain Name, then createobject Array and add to the dictionary
        if rhinoName not in dictionaryRhinoTracks:
            dictionaryRhinoTracks[rhinoName] = gp.createobject("Array")

        # Add Point Object (X & Y coordinates) to the Array       
 dictionaryRhinoTracks[rhinoName].Add(currentPoint)] #Use the dictionary!

    cursor = gp.InsertCursor(featureClassName)
    row = cursor.NewRow()
    for rhinoName in dictionaryRhinoTracks:
        row.Shape = dictionaryRhinoTracks[rhinoName] #Use the dictionary object!
        row.Rhino_Name = rhinoName
        cursor.InsertRow(row)


Instead of this:
        # Check if the Dictionary contains Name, if yes pass, else createobject Array and add to the dictionary
        if rhinoName in dictionaryRhinoTracks:
            pass
        else:
            rhinoTrackArray = gp.createobject("Array")
            dictionaryRhinoTracks[rhinoName] = rhinoTrackArray

        # Check Keys in Dictionary and add Point Object (X & Y coordinates) to the Array       
        for key in dictionaryRhinoTracks:
            if key == rhinoName:            
                rhinoTrackArray.Add(currentPoint)]

    cursor = gp.InsertCursor(featureClassName)
    row = cursor.NewRow()
    for rhinoName in dictionaryRhinoTracks:
        row.Shape = rhinoTrackArray
        row.Rhino_Name = rhinoName
        cursor.InsertRow(row)
0 Kudos
NettoChad
Occasional Contributor
I was running into the same issue and eventually got it work, but knew there had to be a better (shorter) way of doing this. I went from 130 lines of code to 72 lines using your method of "using the dictionary objects".
Thank you
0 Kudos