Re: newbie q

2005-01-13 Thread Will Stuyvesant
I understand you want to do it in an applicative programming style?
Not recommended in general.  But here goes:

.# c.l.p. question:
.# "using map, lambda, reduce, filter and List Comprehensions [x for
.# x in []] just don't get how to add string to all elements of list"
.
.##
.# A function that returns a function, taking a function as argument.
.def allapply(fn):
.def f(seq): return map(fn, seq)
.return f
.
.def add_string_to_element(stringval):
.def f(x): return x + stringval
.return f
.
.add_string_to_all = allapply(add_string_to_element('mystring'))
.
.print add_string_to_all(['d:', 'c:\windows\\','something/'])

this outputs:
['d:mystring', 'c:\\windows\\mystring', 'something/mystring']
-- 
look Ma, no for and no lambda!
-- Will Stuyvesant

-- 
http://mail.python.org/mailman/listinfo/python-list


delay and force in Python

2005-01-19 Thread Will Stuyvesant

Here is a question for people who are more comfortable than
I am with new Python stuff like generators.

I am having fun implementing things from the Wizard book
(Abelson, Sussman, "Structure and Interpretation of Computer
Programs") in Python.  In chapter 3.5 it is about streams as
delayed lists.

Streams are interesting because they are to lists like
xrange is to range.  Could save a lot on memory and
computations.

Below is my straight translation from Scheme code in the
Wizard book to Python.  It works, but now I want to rewrite
the delay and force functions using Python's new stuff,
generators or iterators or what-have-you.  I have the
feeling that that is possible, can you do it?

The program below creates a stream with the numbers 1..995
and then filters the stream, keeping only the even numbers,
and then prints the second number in the stream (implemented
as the first number of the tail, just like in the 3.5
Section in the Wizard book).


. # file: teststreams.py
.
. def delay(exp): return lambda: exp
.
. def force(o): return o()
.
. def cons_stream(a,b): return [a, delay(b)]
.
. def stream_hd(s): return s[0]
.
. # we use tl for cdr
. def tl(x):
. if len(x) == 2: return x[1]
. else: return x[1:]
.
. def stream_tl(s): return force(tl(s))
.
. def stream_enumerate_interval(low, high):
. if low > high:
. return None
. else:
. return cons_stream(
.  low,
.  stream_enumerate_interval(low+1, high))
.
. def stream_filter(pred, s):
. if s is None:
. return None
. elif pred(stream_hd(s)):
. return cons_stream(
.  stream_hd(s),
.  stream_filter(pred, stream_tl(s)))
. else:
. return stream_filter(pred, stream_tl(s))
.
. def isEven(n): return n % 2 == 0
.
. print stream_hd(stream_tl(stream_filter(
.   isEven,
.   stream_enumerate_interval(1,995
. # 4



Something else: this crashes with a "maximum recursion reached"
. print stream_enumerate_interval(1,998)

while this does not crash
. print stream_enumerate_interval(1,900)
this means Python has a maximum of something like 900
recursions?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: delay and force in Python

2005-01-19 Thread Will Stuyvesant

Yes you are right, if you just want to carry an expression
around then lambda does it; but delay was not intended as a
top-level function.  Perhaps you think that my silly stream
implementation in the original post builds the whole list,
but it does not:

>>> o = stream_enumerate_interval(11,121)
>>> print o
[11,  at 0x00BA8670>]
>>> f = o[1]
>>> r = f()
>>> print r
[12,  at 0x00BA86B0>]

instead it builds a list of lambda's, and that is so
desirable 


Others suggested generators indeed, and I can imagine now a
usage pattern like

>>> s = stream_generator(initValue, next, stop, other_params)
>>> stream_hd(stream_tl(stream_filter(isEven,s)))

where the idea is to pass a generator to a function all the
time.  What I don't like though is that I then, as I
understand it, have to code some for-loop inside that
function, I try to avoid for-loops.  But a functional form
defined with a for-loop does not seem all that bad.  Anyway
I have some reading-up to do, about things some posters use
and I forgot to keep up with since I have been coding Python
1.5.2 style for ages now: properties, itertools, ...printed
some stuff already, thanks!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a question

2005-01-19 Thread Will Stuyvesant

Andrew Koenig wrote:
> how about writing this instead?
>
> ('this is a '
>  'long string')

Yes, nice.  And to make that possible we have to write
('one-string-item',) instead of ('one-string-item') if we want a tuple
with one string inside.  Sometimes that feels like a wart to me, but
now I know it, sometimes not.

-- 
http://mail.python.org/mailman/listinfo/python-list


Funny Python error messages

2005-01-21 Thread Will Stuyvesant

Add your funny or surprising Python error messages to this
thread.  A requirement is that you should also show
(minimal) code that produces the message.  Put the code
below, so people can think about how to generate the message
first, a little puzzle if you like.

Perhaps this will even be a useful thread, to brighten the
life of the brave people doing the hard work of providing us
with error messages.

My first one (i'm learning, i'm learning) is

TypeError: 'callable-iterator' object is not callable



#
#
#
#
# >>> it = iter(lambda:0, 0)
# >>> it()
# TypeError: 'callable-iterator' object is not callable

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: delay and force in Python

2005-01-24 Thread Will Stuyvesant
Just for the record, an implementation without using generators,
somewhat like in Sect. 3.5 of the Wizard book, and without recursion
limit problems.
.
. def stream_hd(s): # the head of the stream
. return s[0]
.
. def stream_tl(s): # the tail of the stream
. return s[1]()
.
. ##
. # The low argument is required: the first element of the stream.
. # You either use high= or stop_f= to define the end of the
. # stream.  Omit both for an infinite stream.  stop_f is a function
. # that takes low as argument and returns True or False.
. # The next_f function takes one argument (an element of the stream,
. # same type as the low argument has)
. # The stop_f function takes one argument (same type as low)
. # @param low object
. # @param high object
. # @param next_f function
. # @param stop_f function
. # @return list, a stream
. def make_stream(low, high=None, next_f=None, stop_f=None):
. if next_f is None: next_f = lambda x: x + 1
. if high is not None:# using high
. if low > high:
. return None
. else:
. return [low, lambda: make_stream(
.   next_f(low), high=high, next_f=next_f)]
. elif stop_f is not None:# using stop_f
. if low > stop_f(low):
. return None
. else:
. return [low, lambda: make_stream(
.   next_f(low), next_f=next_f, stop_f=stop_f)]
. else:   # infinite stream
. return [low, lambda: make_stream(
.   next_f(low), next_f=next_f)]
.
. ##
. # iterative version of filter
. # @param pred function, (stream-element) -> bool
. # @param s list, a stream
. # @return list, a stream
. def stream_filter(pred, s):
. if s is None: return []
. while True:
. elem = stream_hd(s)
. if pred(elem):
. return [elem, lambda: stream_filter(pred, stream_tl(s))]
. else:
. s = stream_tl(s)
. if s is None: return []
.
.
. if __name__ == '__main__':
.
. def is100some(x): return x % 100 == 0
. assert(stream_hd(stream_tl(stream_tl(stream_filter(
. is100some,
. make_stream(1, 11) == 300)
.
. def add_33(x): return x + 33
. assert(stream_hd(stream_tl(stream_filter(
. is100some,
. # stream 1,34,67,100,...
. make_stream(1,9, next_f = add_33 == 3400)
.
. assert(stream_hd(stream_tl(stream_filter(
. is100some,
. # infinite stream 1,2,...
. make_stream(1 == 200)
.
. def mod_2(x): return x % 2 == 0
. # this will need more evaluations than the recursion limit count
. infinite_filter = stream_filter(mod_2, make_stream(1))
. assert( stream_hd(stream_tl(infinite_filter)) == 4 )
.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Online Programming Contest

2005-02-24 Thread Will Stuyvesant
> [Varun]
> For details about samhita http://www.samhita.info/

"The Madras Institute of Technology (MIT)" it says there.

The MIT acronym is taken already guys..

-- 
no scheme no glory

-- 
http://mail.python.org/mailman/listinfo/python-list


Python compared with Xen (for XML)

2004-12-03 Thread Will Stuyvesant
Here is a comment on the paper "Programming with Circles,
Triangles and Rectangles" by Erik Meijer, Wolfram Schulte
and Gavin Bierman.  Google will find it quickly if you try.

In the paper they introduce Xen, an extension to C# for
better XML support.  They show how Lifting, Filtering and
Apply-to-all can be done so much better in C# with Xen.

How is Python, my favorite programming language, doing in
this respect?  Let's see:



Python for XML
==


Lifting
---

The example:
"bib.books.title"
[[an expression for all titles of books in bib]]

(stuff in double quotes "..." is suggested Xen code from the
article by E.Meijer et al., stuff in double square brackets
[[...]] is the intended meaning.  Python code is shown after
>>> , the prompt from the Python interactive interpreter.)

We can do this "Lifting" in Python with list comprehension:
>>> [b.title for b in bib.books]


Filtering
-

The example:
"bib.books[it.year >= 1998]"
[[An expression for the books from 1998 or later]]

This can also be done with Python list comprehensions.
>>> [b for b in bib.books if b.year >= 1998]


Apply-to-all


The example:
"bib.books.{print it}"
[[print all books: execute a code block for every book
in .books.]]

I would do it like this in Python:

for b in bib.books:
print b

looks much clearer to me than the .{...} stuff.  Oh and
maybe the new generator expressions can be used for this,
but they are new to me and I can hardly imagine clearer
syntax.  Anyone?

All that is needed for this to work in Python is that you
collect XML attributes in object attributes; and that you
give a name to the XML children of an XML element and put
them as a list into an object attribute with that name.  Go
wild and even define new classes for it dynamically, or
beforehand if you have the XML DTD or Schema.  Not too hard
a programming exercise; who is first?

As for the other content of the article it is my opinion
that they pay way too much attention to data-models and
types, and then strangle themselves trying to fit one
data-model onto another one, and a statically typed one too
for that! (C#, Java, even Visual Basic is mentioned for
laughing out loud).  Better try to get the job done first.

They did this work paid by microsoft.research.  I think
microsoft.research better pay some more attention to Python.
Or are they?  Are the "competitive edge" rumors true?

-- 
http://mail.python.org/mailman/listinfo/python-list


do you master list comprehensions?

2004-12-13 Thread Will Stuyvesant
Here is a question about list comprehensions [lc].  The
question is dumb because I can do without [lc]; but I am
posing the question because I am curious.

This:

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>> result = []
>>> for d in data:
... for w in d:
...result.append(w)
>>> print result
['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

puts all the words in a list, like I want.

How to do this with [lc] instead of for-loops?

I tried funnies like [[w for w in L] for L in data],
that is correct syntax, but you'd never guess.

I know, silly!  No need for [lc]!  So there's my
question.  I am sure a one-liner using [lc] will be very
enlightening.  Like studying LISP.


--
I wish there was a knob on the TV to turn up the intelligence.
There's a knob called `brightness', but it doesn't work.
-- Gallagher

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: do you master list comprehensions?

2004-12-13 Thread Will Stuyvesant
Okay that was fun.  Enlightening as I hoped.  unroll() in Python, for
arbitrary depth, _flatten in Tkinter (what else is in Tkinter!), sum()
abuse.

The sum(data,[]) was funniest, it works like ((['foo','bar'] + []) +
['my','your']) + ['holy','grail'].  Before I think of such things I
have already coded an algorithm in imperative style.  Guess I have not
been exposed to functional programming enough.

-- 
http://mail.python.org/mailman/listinfo/python-list