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 = {}
    </font>
    [/code]



  • 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 &lt;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 to
    xs == 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.


Log in to reply