Refactor a buffered class...

Michael Spencer mahs at telcopartners.com
Wed Sep 6 13:51:04 EDT 2006


lh84777 at yahoo.fr wrote:
> Hello,
> 
> i'm looking for this behaviour and i write a piece of code which works,
> but it looks odd to me. can someone help me to refactor it ?
> 
> i would like to walk across a list of items by series of N (N=3 below)
> of these. i had explicit mark of end of a sequence (here it is '.')
> which may be any length and is composed of words.
> 
> for: s = "this . is a . test to . check if it . works . well . it looks
> . like ."
> the output should be (if grouping by 3) like:
> 
> => this .
> => this . is a .
> => this . is a . test to .
> => is a . test to . check if it .
> => test to . check if it . works .
> => check if it . works . well .
> => works . well . it looks .
> => well . it looks . like .
> 
> my piece of code :
> 
> import sys
> 
> class MyBuffer:
>     def __init__(self):
>         self.acc = []
>         self.sentries = [0, ]
>     def append(self, item):
>         self.acc.append(item)
>     def addSentry(self):
>         self.sentries.append(len(self.acc))
>         print >> sys.stderr, "\t", self.sentries
>     def checkSentry(self, size, keepFirst):
>         n = len(self.sentries) - 1
>         if keepFirst and n < size:
>             return self.acc
>         if n % size == 0:
>             result = self.acc
>             first = self.sentries[1]
>             self.acc = self.acc[first:]
>             self.sentries = [x - first for x in self.sentries]
>             self.sentries.pop(0)
>             return result
> 
> s = "this . is a . test to . check if it . works . well . it looks .
> like ."
> l = s.split()
> print l
> 
> mb = MyBuffer()
> n = 0
> for x in l:
>     mb.append(x)
>     if x == '.':
>         # end of something
>         print "+", n
>         n += 1
>         mb.addSentry()
>         current = mb.checkSentry(3, True) # GROUPING BY 3
>         if current:
>             print "=>", current
> 
If you just need to 'walk across a list of items', then your buffer class and 
helper function seem unnecessary complex.  A generator would do the trick, 
something like:

 >>> def chunker(s, chunk_size=3, sentry="."):
...     buffer=[]
...     sentry_count = 0
...     for item in s:
...         buffer.append(item)
...         if item == sentry:
...             sentry_count += 1
...             if sentry_count > chunk_size:
...                 del buffer[:buffer.index(sentry)+1]
...             yield buffer
...


 >>> s = "this . is a . test to . check if it . works . well . it looks. like ."
 >>> for p in chunker(s.split()): print " ".join(p)
...
this .
this . is a .
this . is a . test to .
is a . test to . check if it .
test to . check if it . works .
check if it . works . well .
works . well . it looks. like .
 >>>

HTH
Michael






More information about the Python-list mailing list