tarsh / pyshp

Automatically exported from code.google.com/p/pyshp
MIT License
0 stars 0 forks source link

Adding keyed dictionary for a record in Writer does not work #1

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.Created keyed dictionary 
sfRecord = {"num1":"bob","num2":"bob2","num3":"bob3"}
2.Add it to the writer
w.field("field1")
w.field("field2")
w.field("field3")
w.record(recordDict=sfRecord)

What is the expected output? What do you see instead?
print sf.records
[]

You should see something.
The issue is in def record(self, *recordList, **recordDict):
...
elif recordDict:
                                for field in self.fields:
                                        if recordDict.get(field[0], None):
                                                record.append(recordDict[field[0]])
Here, recordDict is a keyed object with 'recordDict' as the only keyed object 
in it.
So, replacing recordDict above with recordDict['recordDict'] will get you an 
output.

However, this will still cause an issue where if the key is present but the 
value isn't, the value isn't appended. This causes the later fields to shift.
So an input of this:

sfRecord = {"num1":"bob","num2":"","num3":"bob3"}

will result in an array in record like this:

["bob","bob3"], which is wrong.

Instead we could rewrite the whole block to look something like this (hopefully 
a little more elegant with the names):

recordDict=recordDict['recordDict']
for field in self.fields:
    if field[0] in recordDict:
        record.append(recordDict[field[0]])

Original issue reported on code.google.com by jwdal...@gmail.com on 11 Jan 2011 at 6:36

GoogleCodeExporter commented 9 years ago
Thank you for the bug submission however I'm not sure it's a bug.  

The example provided in the bug report would indeed produce an empty record set 
because the dictionary keys don't match the the field names as specified in the 
documentation string.  This behavior is intended.  The example could be written 
in the following ways and work:

sfRecord = {"num1":"bob","num2":"bob2","num3":"bob3"}
2.Add it to the writer
w.field("num1")
w.field("num2")
w.field("num3")
w.record(recordDict=sfRecord)

sfRecord = {"field1":"bob","field2":"bob2","field3":"bob3"}
2.Add it to the writer
w.field("field1")
w.field("field2")
w.field("field3")
w.record(recordDict=sfRecord)

If I've misunderstood the bug report please don't hesitate to clarify it for me.

Cheers

Original comment by geospati...@gmail.com on 11 Jan 2011 at 7:01

GoogleCodeExporter commented 9 years ago
It looks like I wrote that example incorrectly late in the night. 

From my tests last night (I'll retest tonight to make sure I didn't just mess 
something up), neither of the examples you provided would work.

The reason for this is that the recordDict object is a dict of named arguments, 
one of which has the key 'recordDict'. so recordDict['recordDict'] would have 
the keys "field1", "field2", "field3" (taken from your second example above). 
However, recordDict["field1"], etc. are accessed, but don't exist. This results 
in nothing being appended to the record.

Original comment by jwdal...@gmail.com on 11 Jan 2011 at 7:09

GoogleCodeExporter commented 9 years ago
Ahhhh - I see what you're saying now.  You're right.  An empty dictionary value 
would shift the field values when appended to the dbf.  There needs to be a 
check for both the key and the value.  A null value should be inserted if the 
dictionary doesn't have one.

Original comment by geospati...@gmail.com on 11 Jan 2011 at 10:43

GoogleCodeExporter commented 9 years ago

Original comment by geospati...@gmail.com on 11 Feb 2011 at 3:26

GoogleCodeExporter commented 9 years ago
Not a bug, you misunderstand how keyword arguments work in Python. For the 
example you've specified in your bug report, there are two equivalent ways to 
call this method while passing in keyword arguments:

`w.record(field1='bob', field2='bob2', field3='bob3')`

...or, the method that you're trying to use,

`w.field(**sfRecord)`

The "star star" syntax says "pass this map of key/values as keyword arguments".

Original comment by david.a....@gmail.com on 14 Jan 2012 at 8:48