File I/O self-WTF
-
I was working on an email routing script for a relative of mine, and one of the specifications was that no duplicate emails can arrive within a specific span of time. OK, so I used a dictionary object with the keys being the mails and the values being the last time they were sent, so that if the mail was not in dupes.keys() or dupes[email] = time() - configurable_timespan, it would be OK, but that otherwise it would bounce.
Anyway, I was using pickle to make the object persistent, and I wanted to make sure it would create an empty dictionary if the file was empty. thus, the following code was created:
[code]
if dupe_file.read():
dupes = pickle.load(dupe_file)
else:
dupes = {}
[/code]
multiple hours and bunches of searches for EOFError later, I suddenly realized what was wrong.
-
Arrgggh!
[code]
<font face="Lucida Console" size="2">
if dupe_file.read():
</font><font face="Lucida Console" size="2">dupes = pickle.load(dupe_file)</font><font face="Lucida Console" size="2">else:
</font><font face="Lucida Console" size="2">dupes = {}[/code]
</font>
-
I don't believe this!
<font face="Lucida Console" size="2">
if dupe_file.read():
</font><font face="Lucida Console" size="2">dupes = pickle.load(dupe_file)</font><font face="Lucida Console" size="2">else:
</font><font face="Lucida Console" size="2">dupes = {}</font>
-
I don't know pickle - what's the wtf?
-
Pickle creates persistant objects by serializing them and writing them to a file (and, obviously, by retrieving it).
The
WTF was that since I put a dupe_file.read() statement in the if (to
check if the file has contents), the position I was in the file was the
end of the file. Thus, any request that would have involved reading from the file would have returned an EOFError.
-
I'd laugh, but I've inadvertently done stuff like that myself because my mind was on frying bigger fish.
-
This is a minor wtf, or, as I prefer to call them, 'sleep-deprived wtf' because of the state you're usually in when you write code like this. I've done comparatively stupid things in the past, but one of my favourites was in a mailing on USENET (for the record, something completely different was being discussed, but some illustrative code was needed and this was part of it):
<pre>
let res = any $ zipWith ((x, y) -> x == y) xs ys
</pre>
For the uninitiated, here it is in imperative-pythonesquepseudocode:
<pre>
xs = [List of stuff]
ys = [Another list of stuff]
for x, y in zip(xs, ys):
if x == y:
return True
</pre>
Of course, both of these can be simply reduced to <pre>xs == ys</pre>
PS: will this work? Who knows if the mysterious supposed 'telligent system' will accept the <pre> tags...
-
@Noam Samuel said:
multiple hours and bunches of searches for EOFError later, I suddenly realized what was wrong.I've recently begun converting to Test-Driven Development. I can recommend it.
In this case, one would probably have a test that said (for a well-known pickled state) assert((dupes = pickle.load(dupe_file)) == {...})
(or some similar construct that would compile and otherwise function).
That would have told you whether it worked quite fast... :)
-
@El Foo said:
Of course, both of these can be simply reduced toxs == ys
Definitely not. Your code checks whether *one* of the pairs correspond, while xs == ys checks whether *all* pairs correspond.
Are you sleep deprived right now? ;)
-
As a matter of fact, I was. In the code above, replace '==' with '!=' or '/=' for personal preference, and replace 'True' with 'False'. -Then- it makes sense.