Useful decorator

In the course of writing a bunch of generator-oriented code I kept
wanting to temporarily truncate the output of generators for debugging,
i.e. I might have a function like

def generate_bazillion_items():
for line in bazillion_line_file:
yield itemify(line)

where I wanted to test the program on just the first 20 lines of the
file. After a number of rounds of editing the program to wrap an
xrange(20) loop I went to using islice(bazillion_line_file, 20), but
even more handy was to write this decorator:

Advertisements

Paul Rubin wrote:
> In the course of writing a bunch of generator-oriented code I kept
> wanting to temporarily truncate the output of generators for debugging,
> i.e. I might have a function like
>
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> where I wanted to test the program on just the first 20 lines of the
> file. After a number of rounds of editing the program to wrap an
> xrange(20) loop I went to using islice(bazillion_line_file, 20), but
> even more handy was to write this decorator:
>
> def truncate(n):
> from itertools import islice
> def trunc(gen): # truncate generator to n items
> return lambda *a,**kw: islice(gen(*a,**kw), n)
> return trunc
>
> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.

Thes may be overkill, but how about allowing None as a parameter to
truncate, to allow for programmatic truncation?

Advertisements

On Apr 14, 5:03 pm, Paul Rubin <http://> wrote:
> In the course of writing a bunch of generator-oriented code I kept
> wanting to temporarily truncate the output of generators for debugging,
> i.e. I might have a function like
>
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> where I wanted to test the program on just the first 20 lines of the
> file. After a number of rounds of editing the program to wrap an
> xrange(20) loop I went to using islice(bazillion_line_file, 20), but
> even more handy was to write this decorator:
>
> def truncate(n):
> from itertools import islice
> def trunc(gen): # truncate generator to n items
> return lambda *a,**kw: islice(gen(*a,**kw), n)
> return trunc
>
> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.

On Sat, 14 Apr 2007 15:03:00 -0700, Paul Rubin wrote:
> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.

Steven D'Aprano <> writes:
> if __debug__:
> generate_bazillion_items = truncate(20)(generate_bazillion_items)
>
> Now you don't have to comment/uncomment dozens of lines all over your
> application, but only set a single global.

The cool thing about organizing the program as a generator pipeline is
you only have to comment or uncomment one line .

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!