Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #32312

Re: Style help for a Smalltalk-hack

Path csiph.com!usenet.pasdenom.info!dedibox.gegeweb.org!gegeweb.eu!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!usenet-fr.net!nerim.net!novso.com!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail
Return-Path <ethan@stoneleaf.us>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'skip:[ 20': 0.03; 'binary': 0.05; 'chunk': 0.07; 'subject:help': 0.07; 'python': 0.09; 'appropriate.': 0.09; 'bytes,': 0.09; 'formatted': 0.09; 'from:addr:ethan': 0.09; 'from:addr:stoneleaf.us': 0.09; 'from:name:ethan furman': 0.09; 'generators': 0.09; 'message- id:@stoneleaf.us': 0.09; 'read()': 0.09; 'received:184.172': 0.09; 'received:gator410.hostgator.com': 0.09; '~ethan~': 0.09; 'cc:addr :python-list': 0.10; 'def': 0.10; 'adjacent': 0.16; 'chunk)': 0.16; 'chunk:': 0.16; 'filename):': 0.16; 'invocations': 0.16; 'iteration,': 0.16; 'iterator': 0.16; 'received:69.41.248': 0.16; 'stream.': 0.16; 'travis': 0.16; 'wrote:': 0.17; 'byte': 0.17; 'bytes': 0.17; 'detect': 0.17; 'code,': 0.18; 'module': 0.19; 'file.': 0.20; 'interpret': 0.22; 'cc:2**0': 0.23; 'split': 0.23; 'raise': 0.24; 'cc:no real name:2**0': 0.24; 'cc:addr:python.org': 0.25; 'header:In-Reply-To:1': 0.25; 'header:User-Agent:1': 0.26; 'looks': 0.26; 'values': 0.26; 'bugs': 0.27; 'checking': 0.27; "doesn't": 0.28; 'lines': 0.28; 'signatures': 0.29; 'styles': 0.29; 'skip:_ 10': 0.29; 'class': 0.29; "i'm": 0.29; "we're": 0.30; 'that.': 0.30; 'error': 0.30; 'code': 0.31; 'skip:s 30': 0.33; 'like:': 0.33; 'another': 0.33; "can't": 0.34; 'skip:b 20': 0.34; 'self': 0.34; 'something': 0.35; 'there': 0.35; 'next': 0.35; 'add': 0.36; 'but': 0.36; '(i.e.': 0.36; 'skip:g 30': 0.36; 'charset:us-ascii': 0.36; 'does': 0.37; 'two': 0.37; 'skip:v 20': 0.37; 'subject:: ': 0.38; 'some': 0.38; 'where': 0.40; 'subject:-': 0.40; 'header:Received:5': 0.40; 'help': 0.40; 'end': 0.40; 'your': 0.60; 'first': 0.61; 'different': 0.63; 'more': 0.63; 'other.': 0.64; 'sit': 0.65; 'gap': 0.84
Date Sun, 28 Oct 2012 06:31:10 -0700
From Ethan Furman <ethan@stoneleaf.us>
User-Agent Thunderbird 1.5.0.10 (Windows/20070221)
MIME-Version 1.0
To Travis Griggs <travisgriggs@gmail.com>
Subject Re: Style help for a Smalltalk-hack
References <168DF25C-0C43-45F2-BEDC-17AC4210F207@gmail.com>
In-Reply-To <168DF25C-0C43-45F2-BEDC-17AC4210F207@gmail.com>
Content-Type text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding 7bit
X-AntiAbuse This header was added to track abuse, please include it with any abuse report
X-AntiAbuse Primary Hostname - gator410.hostgator.com
X-AntiAbuse Original Domain - python.org
X-AntiAbuse Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse Sender Address Domain - stoneleaf.us
X-BWhitelist no
X-Source
X-Source-Args
X-Source-Dir
X-Source-Sender ([192.168.11.4]) [173.12.184.238]:49262
X-Source-Auth ethan+stoneleaf.us
X-Email-Count 2
X-Source-Cap dG9idWs7dG9idWs7Z2F0b3I0MTAuaG9zdGdhdG9yLmNvbQ==
Cc python-list@python.org
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.2970.1351431671.27098.python-list@python.org> (permalink)
Lines 51
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1351431671 news.xs4all.nl 6879 [2001:888:2000:d::a6]:43127
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:32312

Show key headers only | View raw


Travis Griggs wrote:
> I'm writing some code that does a structured read from formatted binary file. The code I came up with looks like:
> 
> # get the first four bytes, the first gap field
> chunk = byteStream.read(4)
> while chunk:
>     # interpret the gap bytes
>     gap, = struct.unpack('>I', chunk)
>     # suck off the valveCount
>     valveCount, = struct.unpack('>I', byteStream.read(4))
>     # collect the next valveCount signatures
>     signatures = [struct.unpack('>I', byteStream.read(4))[0] for _ in range(valveCount)]
>     self.script.append(ScriptSpan(gap=gap, valveSet=signatures))
>     # now get the next 4 bytes for the gap of the next iteration, it'll be empty if we're at end
>     chunk = byteStream.read(4)
> 
> I can't help but thinking that there's some better way (i.e. more pythonic) to do this that doesn't involve having to use another module (Construct) or exploring generators or something like that. What bugs me about it is that there is two different styles for reading/decoding values from the byte stream. valveCount and signatures are both paired invocations of unpack() and read(). But to detect the end of the stream (file), I have to split the read() and unpack() of the gap value across 3 different lines of the code, and they don't even sit adjacent to each other.

What do you have against generators?  ;)

How about an iterator approach:

8<-------------------------------------------------------
class Gap_Valve_Reader(object):  # untested
     def __init__(self, filename):
         self.byteStream = open(filename)
     def __iter__(self):
         return self
     def __next__(self):                 # python 3 name
         chunk = self.byteStream.read(8)
         if not chunk:
             self.byteStream.close()
             raise StopIteration
         gap, valveCount = struct.unpack('>II', chunk)
         signatures = struct.unpack('>%sI' % valveCount,
                     self.byteStream.read(4 * valueCount))
         return gap, signatures
     next = __next__  # python 2 name
8<-------------------------------------------------------

then your main code can look like:

8<-------------------------------------------------------
gvr = Gap_Valve_Reader('binary_file.bin')
for gap, signatures in gvr:
     self.script.append(ScriptSpan(gap=gap, valveSet=signatures))
8<-------------------------------------------------------

Don't forget to add error checking where appropriate.

~Ethan~

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Style help for a Smalltalk-hack Ethan Furman <ethan@stoneleaf.us> - 2012-10-28 06:31 -0700

csiph-web