Re: A gnarly little python loop

2012-11-11 Thread Stefan Behnel
Steve Howell, 11.11.2012 04:03:
> On Nov 10, 2:58 pm, Roy Smith  wrote:
>> I'm trying to pull down tweets with one of the many twitter APIs.  The
>> particular one I'm using (python-twitter), has a call:
>>
>> data = api.GetSearch(term="foo", page=page)
>>
>> The way it works, you start with page=1.  It returns a list of tweets.
>> If the list is empty, there are no more tweets.  If the list is not
>> empty, you can try to get more tweets by asking for page=2, page=3, etc.
>> I've got:
>>
>> page = 1
>> while 1:
>> r = api.GetSearch(term="foo", page=page)
>> if not r:
>> break
>> for tweet in r:
>> process(tweet)
>> page += 1
>>
>> It works, but it seems excessively fidgety.  Is there some cleaner way
>> to refactor this?
> 
> I think your code is perfectly readable and clean, but you can flatten
> it like so:
> 
> def get_tweets(term, get_page):
> page_nums = itertools.count(1)
> pages = itertools.imap(api.getSearch, page_nums)
> valid_pages = itertools.takewhile(bool, pages)
> tweets = itertools.chain.from_iterable(valid_pages)
> return tweets

I'd prefer the original code ten times over this inaccessible beast.

Stefan


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


Re: KAJOL SEX VIDEOS'''''''''''''''''''

2012-11-11 Thread nagurbasha55
On Thursday, August 2, 2012 10:05:25 PM UTC+5:30, devi wrote:
> KAJAL SEX VIDEOS
> 
> http://maxworkerds.co.cc

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


Re: A gnarly little python loop

2012-11-11 Thread Cameron Simpson
On 11Nov2012 08:56, Stefan Behnel  wrote:
| Steve Howell, 11.11.2012 04:03:
| > On Nov 10, 2:58 pm, Roy Smith  wrote:
| >> page = 1
| >> while 1:
| >> r = api.GetSearch(term="foo", page=page)
| >> if not r:
| >> break
| >> for tweet in r:
| >> process(tweet)
| >> page += 1
| >>
| >> It works, but it seems excessively fidgety.  Is there some cleaner way
| >> to refactor this?
| > 
| > I think your code is perfectly readable and clean, but you can flatten
| > it like so:
| > 
| > def get_tweets(term, get_page):
| > page_nums = itertools.count(1)
| > pages = itertools.imap(api.getSearch, page_nums)
| > valid_pages = itertools.takewhile(bool, pages)
| > tweets = itertools.chain.from_iterable(valid_pages)
| > return tweets
| 
| I'd prefer the original code ten times over this inaccessible beast.

Me too.
-- 
Cameron Simpson 

In an insane society, the sane man must appear insane.
- Keith A. Schauer 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A gnarly little python loop

2012-11-11 Thread Paul Rubin
Cameron Simpson  writes:
> | I'd prefer the original code ten times over this inaccessible beast.
> Me too.

Me, I like the itertools version better.  There's one chunk of data
that goes through a succession of transforms each of which
is very straightforward.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a simpler way to modify all arguments in a function before using the arguments?

2012-11-11 Thread Peter Otten
Aahz wrote:

> In article ,
> Peter Otten  <__pete...@web.de> wrote:
>>Miki Tebeka wrote:
>>
 Is there a simpler way to modify all arguments in a function before
 using the arguments?
>>>
>>> You can use a decorator:
>>> 
>>> from functools import wraps
>>> 
>>> def fix_args(fn):
>>> @wraps(fn)
>>> def wrapper(*args):
>>> args = (arg.replace('_', '') for arg in args)
>>> return fn(*args)
>>> 
>>> return wrapper
>>> 
>>> @fix_args
>>> def foo(x, y):
>>> print(x)
>>> print(y)
>>
>>I was tempted to post that myself, but he said /simpler/ ;)
> 
> From my POV, that *is* simpler.  When you change the parameters for foo,
> you don't need to change the arg pre-processing.  Also allows code reuse,
> probably any program needing this kind of processing once will need it
> again.

Typical changes would be

@fix_args
def bar(x, y=None):
print(x)
print(y)

@fix_args
def baz(file, x, y):
print(s, file=file)

Do you find it obvious what 

bar("a_b")
bar("a_b", y="c_d")

print? Do you find the traceback produced by the latter helpful?
Moving complexity into a helper function often makes client code simpler 
because if the helper is well-tested and preferrably maintained by someone 
else the part that you have to deal with becomes simpler, but the overall 
complexity still increases.
A fix_args() decorator is worthwhile only if you need it more than once or 
twice, and because it is hard to generalise I expect that yagni.




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


Re: A gnarly little python loop

2012-11-11 Thread Peter Otten
Paul Rubin wrote:

> Cameron Simpson  writes:
>> | I'd prefer the original code ten times over this inaccessible beast.
>> Me too.
> 
> Me, I like the itertools version better.  There's one chunk of data
> that goes through a succession of transforms each of which
> is very straightforward.

[Steve Howell]
> def get_tweets(term, get_page):
> page_nums = itertools.count(1)
> pages = itertools.imap(api.getSearch, page_nums)
> valid_pages = itertools.takewhile(bool, pages)
> tweets = itertools.chain.from_iterable(valid_pages)
> return tweets
 

But did you spot the bug(s)?
My itertools-based version would look like this

def get_tweets(term):
pages = (api.GetSearch(term, pageno)
 for pageno in itertools.count(1))
for page in itertools.takewhile(bool, pages):
yield from page

but I can understand that it's not everybody's cup of tea.

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


Re: Printing characters outside of the ASCII range

2012-11-11 Thread danielk
On Friday, November 9, 2012 5:11:12 PM UTC-5, Ian wrote:
> On Fri, Nov 9, 2012 at 2:46 PM, danielk  wrote:
> 
> > D:\home\python>pytest.py
> 
> > Traceback (most recent call last):
> 
> >   File "D:\home\python\pytest.py", line 1, in 
> 
> > print(chr(253).decode('latin1'))
> 
> > AttributeError: 'str' object has no attribute 'decode'
> 
> >
> 
> > Do I need to import something?
> 
> 
> 
> Ramit should have written "encode", not "decode".  But the above still
> 
> would not work, because chr(253) gives you the character at *Unicode*
> 
> code point 253, not the character with CP437 ordinal 253 that your
> 
> terminal can actually print.  The Unicode equivalents of those
> 
> characters are:
> 
> 
> 
> >>> list(map(ord, bytes([252, 253, 254]).decode('cp437')))
> 
> [8319, 178, 9632]
> 
> 
> 
> So these are what you would need to encode to CP437 for printing.
> 
> 
> 
> >>> print(chr(8319))
> 
> ⁿ
> 
> >>> print(chr(178))
> 
> ²
> 
> >>> print(chr(9632))
> 
> ■
> 
> 
> 
> That's probably not the way you want to go about printing them,
> 
> though, unless you mean to be inserting them manually.  Is the data
> 
> you get from your database a string, or a bytes object?  If the
> 
> former, just do:
> 
> 
> 
> print(data.encode('cp437'))
> 
> 
> 
> If the latter, then it should be printable as is, unless it is in some
> 
> other encoding than CP437.

Ian's solution gives me what I need (thanks Ian!). But I notice a difference 
between '__str__' and '__repr__'.

class Pytest(str):
def __init__(self, data = None):
if data == None: data = ""
self.data = data

def __repr__(self):
return (self.data).encode('cp437')

>>> import pytest
>>> p = pytest.Pytest("abc" + chr(178) + "def")
>>> print(p)
abc²def
>>> print(p.data)
abc²def
>>> print(type(p.data))


If I change '__repr__' to '__str__' then I get:

>>> import pytest
>>> p = pytest.Pytest("abc" + chr(178) + "def")
>>> print(p)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: __str__ returned non-string (type bytes)

Why is '__str__' behaving differently than '__repr__' ? I'd like to be able to 
use '__str__' because the result is not executable code, it's just a string of 
the record contents.

The documentation for the 'encode' method says: "Return an encoded version of 
the string as a bytes object." Yet when I displayed the type, it said it was 
, which I'm taking to be 'type string', or can a 'string' also be 
'a string of bytes' ?

I'm trying to get my head around all this codecs/unicode stuff. I haven't had 
to deal with it until now but I'm determined to not let it get the best of me 
:-)

My goals are:

a) display a 'raw' database record with the delimiters intact, and
b) allow the client to create a string that represents a database record. So, 
if they know the record format then they should be able to create a database 
object like it does above, but with the chr(25x) characters. I will handle the 
conversion of the chr(25x) characters internally.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Oscar Benjamin
On 11 November 2012 02:47, Chris Angelico  wrote:
> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly  wrote:
>> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico  wrote:
>>> I would not assume that. The origin is a point, just like any other.
>>> With a Line class, you could deem a zero-length line to be like a
>>> zero-element list, but Point(0,0) is more like the tuple (0,0) which
>>> is definitely True.
>>
>> It's more like the number 0 than the tuple (0,0).
>>
>> 0 is the origin on a 1-dimensional number line.
>> (0,0) is the origin on a 2-dimensional number plane.
>>
>> In fact, it might be pointed out that Point(0, 0) is a generalization
>> of 0+0j, which is equal to 0.
>
> Ah, good point. In any case, though, it'd be an utterly inconsequential bug.

You were right the first time, Chris. A point that happens to coincide
with the arbitrarily chosen origin is no more truthy or falsey than
any other. A vector of length 0 on the other hand is a very different
beast.

The significance of zero in real algebra is not that it is the origin
but rather that it is the additive and multiplicative zero:

   a + 0 = a  for any real number a
   a * 0 = 0 for any real number a

The same is true for a vector v0, of length 0:

   v + v0 = v for any vector v
   a * v0 = v0 for any scalar a

There is however no meaningful sense in which points (as opposed to
vectors) can be added to each other or multiplied by anything, so
there is no zero point.

The relationship between points and vectors is analogous to the
relationship between datetimes and timedeltas. Having Vector(0, 0)
evaluate to False is analogous to having timedelta(0) evaluate to
False and is entirely sensible. Having Point(0, 0) evaluate to False
is precisely the same conceptual folly that sees midnight evaluate as
False.


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


Re: Printing characters outside of the ASCII range

2012-11-11 Thread Thomas Rachel

Am 09.11.2012 18:17 schrieb danielk:


I'm using this character as a delimiter in my application.


Then you probably use the *byte* 254 as opposed to the *character* 254.

So it might be better to either switch to byte strings, or output the 
representation of the string instead of itself.


So do print(repr(chr(254))) or, for byte strings, print(bytes([254])).


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


Question about email.message_from_string() and Message objects

2012-11-11 Thread tinnews
I'm a little confused about the relationship between the Python
email.parser convenience function email.message_from_string() and the
mailbox.Message objects.

If I want an mailbox.mboxMessage given the message as a stream of text
is the right way to do it as follows (or at least a reasonable way to
do it):-

msg = email.message_from_string(messageAsAString)

mbxMsg = mailbox.mboxMessage(msg)

Or can I go direct to mbox by doing:-

mbxMsg = mailbox.mboxMessage(messageAsAString)

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


Re: Printing characters outside of the ASCII range

2012-11-11 Thread Lele Gaifax
danielk  writes:

> Ian's solution gives me what I need (thanks Ian!). But I notice a
> difference between '__str__' and '__repr__'.
>
> class Pytest(str):
> def __init__(self, data = None):
> if data == None: data = ""
> self.data = data
>
> def __repr__(self):
> return (self.data).encode('cp437')
>

The correct way of comparing with None (and in general with
“singletons”) is with the “is” operator, not with “==”.

> If I change '__repr__' to '__str__' then I get:
>
 import pytest
 p = pytest.Pytest("abc" + chr(178) + "def")
 print(p)
> Traceback (most recent call last):
>   File "", line 1, in 
> TypeError: __str__ returned non-string (type bytes)

In Python 3.3 there is one kind of string, the one that under Python 2.x
was called “unicode”. When you encode such a string with a specific
encoding you obtain a plain “bytes array”. No surprise that the
__str__() method complains, it's called like that for a reason :)

> I'm trying to get my head around all this codecs/unicode stuff. I
> haven't had to deal with it until now but I'm determined to not let it
> get the best of me :-)

Two good readings on the subject:

- http://nedbatchelder.com/text/unipain.html
- http://www.joelonsoftware.com/articles/Unicode.html

ciao, lele.
-- 
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
l...@metapensiero.it  | -- Fortunato Depero, 1929.

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


Re: A gnarly little python loop

2012-11-11 Thread Steve Howell
On Sunday, November 11, 2012 1:54:46 AM UTC-8, Peter Otten wrote:
> Paul Rubin wrote:
> 
> 
> 
> > Cameron Simpson  writes:
> 
> >> | I'd prefer the original code ten times over this inaccessible beast.
> 
> >> Me too.
> 
> > 
> 
> > Me, I like the itertools version better.  There's one chunk of data
> 
> > that goes through a succession of transforms each of which
> 
> > is very straightforward.
> 
> 
> 
> [Steve Howell]
> 
> > def get_tweets(term, get_page):
> 
> > page_nums = itertools.count(1)
> 
> > pages = itertools.imap(api.getSearch, page_nums)
> 
> > valid_pages = itertools.takewhile(bool, pages)
> 
> > tweets = itertools.chain.from_iterable(valid_pages)
> 
> > return tweets
> 
>  
> 
> 
> 
> But did you spot the bug(s)?
> 

My first version was sketching out the technique, and I don't have handy access 
to the API.

Here is an improved version:

def get_tweets(term):
def get_page(page):
return getSearch(term, page)
page_nums = itertools.count(1)
pages = itertools.imap(get_page, page_nums)
valid_pages = itertools.takewhile(bool, pages)
tweets = itertools.chain.from_iterable(valid_pages)
return tweets

for tweet in get_tweets("foo"):
process(tweet)

This is what I used to test it:


def getSearch(term = "foo", page = 1):
# simulate api for testing
if page < 5:
return [
'page %d, tweet A for term %s' % (page, term),
'page %d, tweet B for term %s' % (page, term),
]
else:
return None

def process(tweet):
print tweet
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A gnarly little python loop

2012-11-11 Thread Steve Howell
On Nov 11, 1:09 am, Paul Rubin  wrote:
> Cameron Simpson  writes:
> > | I'd prefer the original code ten times over this inaccessible beast.
> > Me too.
>
> Me, I like the itertools version better.  There's one chunk of data
> that goes through a succession of transforms each of which
> is very straightforward.

Thanks, Paul.

Even though I supplied the "inaccessible" itertools version, I can
understand why folks find it inaccessible.  As I said to the OP, there
was nothing wrong with the original imperative approach; I was simply
providing an alternative.

It took me a while to appreciate itertools, but the metaphor that
resonates with me is a Unix pipeline.  It's just a metaphor, so folks
shouldn't be too literal, but the idea here is this:

  page_nums -> pages -> valid_pages -> tweets

The transforms are this:

  page_nums -> pages: call API via imap
  pages -> valid_pages: take while true
  valid_pages -> tweets: use chain.from_iterable to flatten results

Here's the code again for context:

def get_tweets(term):
def get_page(page):
return getSearch(term, page)
page_nums = itertools.count(1)
pages = itertools.imap(get_page, page_nums)
valid_pages = itertools.takewhile(bool, pages)
tweets = itertools.chain.from_iterable(valid_pages)
return tweets

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


Re: Question about email.message_from_string() and Message objects

2012-11-11 Thread tinnews
tinn...@isbd.co.uk wrote:
> I'm a little confused about the relationship between the Python
> email.parser convenience function email.message_from_string() and the
> mailbox.Message objects.
> 
> If I want an mailbox.mboxMessage given the message as a stream of text
> is the right way to do it as follows (or at least a reasonable way to
> do it):-
> 
> msg = email.message_from_string(messageAsAString)
> 
> mbxMsg = mailbox.mboxMessage(msg)
> 
> Or can I go direct to mbox by doing:-
> 
> mbxMsg = mailbox.mboxMessage(messageAsAString)
> 
Answered myself by just trying it, the simple, straightforward 

mbxMsg = mailbox.mboxMessage(messageAsAString)

works perfectly.

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


Re: Is there a simpler way to modify all arguments in a function before using the arguments?

2012-11-11 Thread Steve Howell
On Nov 9, 4:48 pm, bruceg113...@gmail.com wrote:
> Is there a simpler way to modify all arguments in a function before using the 
> arguments?
>
> For example, can the below code, in the modify arguments section be made into 
> a few statements?
>
>     def someComputation (aa, bb, cc, dd, ee, ff, gg, hh):
>        # modify arguments
>        # --
>         aa = aa.replace (“_” , “”)
>         bb=  bb.replace (“_” , “”)
>         cc = cc.replace (“_” , “”)
>         dd = dd.replace (“_” , “”)
>         ee = ee.replace (“_” , “”)
>         ff = ff.replace (“_” , “”)
>         gg = gg.replace (“_” , “”)
>         hh = hh.replace (“_” , “”)
>
>        # use the arguments
>        # -
>        # …

I would couch this problem in a little more specific terms than trying
to make this "simpler."

The word "simple" is a dangerous term, because it's so broad and
subjective.  By my mind, the code is already simple, but that's just
my own two cents.

The real problem with the code that it's a maintenance trap, because a
careless developer could add the ii parameter and forget to clean the
output.  So the problem statement here might be more like "How do I
make sure future developers don't forget to fix the underscores in
future args?".  That's still a controversial question, but at least
it's a little more specific.

The other problem with the current code is that all the boilerplate
distracts from the real logic of the function.  That's a valid
concern, although it's likely that most maintainers of the code would
simply page down past the boilerplate without too much complaint.
-- 
http://mail.python.org/mailman/listinfo/python-list


logging, can one get it to email messages over a certain level?

2012-11-11 Thread tinnews
I'm sure this must be possible but at the moment I can't see how to do it.

I want to send an E-Mail when the logging module logs a message above
a certain level (probably for ERROR and CRITICAL messages only).

I.e. I want some sort of hook that will be called when these messages
are logged (I can do the sendmail bit OK, I've got code that does that).

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


Re: logging, can one get it to email messages over a certain level?

2012-11-11 Thread Steve Howell
On Nov 11, 9:48 am, tinn...@isbd.co.uk wrote:
> I'm sure this must be possible but at the moment I can't see how to do it.
>
> I want to send an E-Mail when the logging module logs a message above
> a certain level (probably for ERROR and CRITICAL messages only).
>
> I.e. I want some sort of hook that will be called when these messages
> are logged (I can do the sendmail bit OK, I've got code that does that).
>
> --
> Chris Green

Scroll down to the Handlers section here:

   http://docs.python.org/2/howto/logging.html#logging-basic-tutorial

I'm not sure this explains perfectly what you're gonna need to do, but
I hope it gets you in the ballpark.

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


Re: A gnarly little python loop

2012-11-11 Thread Peter Otten
Steve Howell wrote:

> On Nov 11, 1:09 am, Paul Rubin  wrote:
>> Cameron Simpson  writes:
>> > | I'd prefer the original code ten times over this inaccessible beast.
>> > Me too.
>>
>> Me, I like the itertools version better.  There's one chunk of data
>> that goes through a succession of transforms each of which
>> is very straightforward.
> 
> Thanks, Paul.
> 
> Even though I supplied the "inaccessible" itertools version, I can
> understand why folks find it inaccessible.  As I said to the OP, there
> was nothing wrong with the original imperative approach; I was simply
> providing an alternative.
> 
> It took me a while to appreciate itertools, but the metaphor that
> resonates with me is a Unix pipeline.  It's just a metaphor, so folks
> shouldn't be too literal, but the idea here is this:
> 
>   page_nums -> pages -> valid_pages -> tweets
> 
> The transforms are this:
> 
>   page_nums -> pages: call API via imap
>   pages -> valid_pages: take while true
>   valid_pages -> tweets: use chain.from_iterable to flatten results
> 
> Here's the code again for context:
> 
> def get_tweets(term):
> def get_page(page):
> return getSearch(term, page)
> page_nums = itertools.count(1)
> pages = itertools.imap(get_page, page_nums)
> valid_pages = itertools.takewhile(bool, pages)
> tweets = itertools.chain.from_iterable(valid_pages)
> return tweets
> 

Actually you supplied the "accessible" itertools version. For reference, 
here's the inaccessible version:

class api:
"""Twitter search API mock-up"""
pages = [
["a", "b", "c"],
["d", "e"],
]
@staticmethod
def GetSearch(term, page):
assert term == "foo"
assert page >= 1
if page > len(api.pages):
return []
return api.pages[page-1]

from collections import deque
from functools import partial
from itertools import chain, count, imap, takewhile

def process(tweet):
print tweet

term = "foo"

deque(
imap(
process,
chain.from_iterable(
takewhile(bool, imap(partial(api.GetSearch, term), count(1),
maxlen=0)

;)

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


Re: A gnarly little python loop

2012-11-11 Thread Steve Howell
On Nov 11, 10:34 am, Peter Otten <__pete...@web.de> wrote:
> Steve Howell wrote:
> > On Nov 11, 1:09 am, Paul Rubin  wrote:
> >> Cameron Simpson  writes:
> >> > | I'd prefer the original code ten times over this inaccessible beast.
> >> > Me too.
>
> >> Me, I like the itertools version better.  There's one chunk of data
> >> that goes through a succession of transforms each of which
> >> is very straightforward.
>
> > Thanks, Paul.
>
> > Even though I supplied the "inaccessible" itertools version, I can
> > understand why folks find it inaccessible.  As I said to the OP, there
> > was nothing wrong with the original imperative approach; I was simply
> > providing an alternative.
>
> > It took me a while to appreciate itertools, but the metaphor that
> > resonates with me is a Unix pipeline.  It's just a metaphor, so folks
> > shouldn't be too literal, but the idea here is this:
>
> >   page_nums -> pages -> valid_pages -> tweets
>
> > The transforms are this:
>
> >   page_nums -> pages: call API via imap
> >   pages -> valid_pages: take while true
> >   valid_pages -> tweets: use chain.from_iterable to flatten results
>
> > Here's the code again for context:
>
> >     def get_tweets(term):
> >         def get_page(page):
> >             return getSearch(term, page)
> >         page_nums = itertools.count(1)
> >         pages = itertools.imap(get_page, page_nums)
> >         valid_pages = itertools.takewhile(bool, pages)
> >         tweets = itertools.chain.from_iterable(valid_pages)
> >         return tweets
>
> Actually you supplied the "accessible" itertools version. For reference,
> here's the inaccessible version:
>
> class api:
>     """Twitter search API mock-up"""
>     pages = [
>         ["a", "b", "c"],
>         ["d", "e"],
>         ]
>     @staticmethod
>     def GetSearch(term, page):
>         assert term == "foo"
>         assert page >= 1
>         if page > len(api.pages):
>             return []
>         return api.pages[page-1]
>
> from collections import deque
> from functools import partial
> from itertools import chain, count, imap, takewhile
>
> def process(tweet):
>     print tweet
>
> term = "foo"
>
> deque(
>     imap(
>         process,
>         chain.from_iterable(
>             takewhile(bool, imap(partial(api.GetSearch, term), count(1),
>     maxlen=0)
>
> ;)

I know Peter's version is tongue in cheek, but I do think that it has
a certain expressive power, and it highlights three mind-expanding
Python modules.

Here's a re-flattened take on Peter's version ("Flat is better than
nested." -- PEP 20):

term = "foo"
search = partial(api.GetSearch, term)
nums = count(1)
paged_tweets = imap(search, nums)
paged_tweets = takewhile(bool, paged_tweets)
tweets = chain.from_iterable(paged_tweets)
processed_tweets = imap(process, tweets)
deque(processed_tweets, maxlen=0)

The use of deque to exhaust an iterator is slightly overboard IMHO,
but all the other lines of code can be fairly easily understood once
you read the docs.

partial: http://docs.python.org/2/library/functools.html
count, imap, takewhile, chain.from_iterable:
http://docs.python.org/2/library/itertools.html
deque: http://docs.python.org/2/library/collections.html

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


Re: A gnarly little python loop

2012-11-11 Thread Roy Smith
In article ,
 Peter Otten <__pete...@web.de> wrote:
 
> deque(
> imap(
> process,
> chain.from_iterable(
> takewhile(bool, imap(partial(api.GetSearch, term), count(1),
> maxlen=0)
> 
> ;)

If I wanted STL, I would still be writing C++ :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: problem with module PyVisa

2012-11-11 Thread Jean Dubois
On 9 nov, 22:14, w...@mac.com wrote:
> On Nov 9, 2012, at 3:43 PM, Jean Dubois  wrote:
>
>
>
>
>
>
>
>
>
>
>
> > The error may be obvious but finding this file and how to install it
> > is not unfortunately.
> > It seems I have to install it from the National Instruments site but
> > Debian Linux doesn't seem to be supported...
> > and I doubt whether just copying this file will be sufficient to make
> > PyVisa work.
> > I wonder whether there might be another way to communicate via USB
> > with a Keithley programmable power supply using Python.
>
> > best regards,
> > Jean
>
> > --
> >http://mail.python.org/mailman/listinfo/python-list
>
> I've been using pyserial quite successfully to control a USB-to-serial 
> converter.
>
> That is, controlling a couple of RS232 serial devices via the USB port 
> through a KeySpan USB-to-Serial converter.
>
> Pyserial seems to make communication through the USB port quite transparent, 
> at least on my OS-X system.
>
> -Bill

Well, in fact I do have some working scripts using pyserial to control
an older (and more expensive) Keithley sourcemeter in combination with
a USB-to-serial converter.
But the trouble started when buying a cheaper and newer Keithley model
which does not have rs232 but only USB. I noticed they have put an
extra layer above USB called USBTMC
which complicates things further. I followed the instructions at
http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.htm?&cc=BE&lc=dut#3.Copyright%20Notice|outline
and compiled and loaded the usbtmc-driver but I still can't
communicate with the Keithley, hence I started looking for an
alternative using PyVisa...and now I'm stuck

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


List comprehension for testing **params

2012-11-11 Thread Cantabile

Hi,
I'm writing a small mail library for my own use, and at the time I'm 
testing parameters like this:


class Mail(object):
def __init__(self, smtp, login, **params)
blah
blah
required = ['Subject', 'From', 'To', 'msg']
for i in required:
if not i in params.keys():
print "Error, \'%s\' argument is missing" %i
exit(1)
...

md = {'Subject' : 'Test', 'From' :'Me', 'To' :['You', 'Them'], 'msg' 
:my.txt"}


m = Mail('smtp.myprovider.com', ["mylogin", "mypasswd"], **md)



I'd like to do something like that instead of the 'for' loop in __init__:

assert[key for key in required if key in params.keys()]

but it doesn't work. It doesn't find anythin wrong if remove, say msg, 
from **md. I thought it should because I believed that this list 
comprehension would check that every keyword in required would have a 
match in params.keys.


Could you explain why it doesn't work and do you have any idea of how it 
could work ?


Thanks in advance :)
Cheers,
Cantabile



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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Steven D'Aprano
On Sun, 11 Nov 2012 14:21:19 +, Oscar Benjamin wrote:

> On 11 November 2012 02:47, Chris Angelico  wrote:
>> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly 
>> wrote:
>>> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico 
>>> wrote:
 I would not assume that. The origin is a point, just like any other.
 With a Line class, you could deem a zero-length line to be like a
 zero-element list, but Point(0,0) is more like the tuple (0,0) which
 is definitely True.

Don't conflate the set of all tuples of arbitrary length with points, 
which have fixed length. Points are not *sequences* -- in Python, we 
treat tuples as sequences first and records second, because that is a 
useful thing to do. (But it is not the only useful thing to do: if we 
treated them as records first and sequences second, we might want to say 
that a tuple t was falsey if all the fields in t were falsey.)

In the case of a Point class, a Point is definitely not a sequence. That 
we put the x-coordinate first and the y-coordinate second is a mere 
convention, like writing left to right. The mathematical properties of 
points do not depend on the x-coordinate coming first. Since points 
should not be treated as sequences, the requirement that non-empty 
sequences be treated as truthy is irrelevant.


>>> It's more like the number 0 than the tuple (0,0).
>>>
>>> 0 is the origin on a 1-dimensional number line. (0,0) is the origin on
>>> a 2-dimensional number plane.
>>>
>>> In fact, it might be pointed out that Point(0, 0) is a generalization
>>> of 0+0j, which is equal to 0.
>>
>> Ah, good point. In any case, though, it'd be an utterly inconsequential
>> bug.
> 
> You were right the first time, Chris. A point that happens to coincide
> with the arbitrarily chosen origin is no more truthy or falsey than any
> other. A vector of length 0 on the other hand is a very different beast.

Nonsense. The length and direction of a vector is relative to the origin. 
If the origin is arbitrary, as you claim, then so is the length of the 
vector.

Just because we can perform vector transformations on the plane to move 
the origin to some point other that (0,0) doesn't make (0,0) an 
"arbitrarily chosen origin". It is no more arbitrary than 0 as the origin 
of the real number line.

And yes, we can perform 1D vector transformations on the real number line 
too. Here's a version of range that sets the origin to 42, not 0:

def myrange(start, end=None, step=1):
if end is None:
start = 42
return range(start, end, step)


Nevertheless, there really is something special about the point 0 on the 
real number line, the point (0,0) on the complex number plane, the point 
(0,0,0) in the 3D space, (0,0,0,0) in 4D space, etc. It is not just an 
arbitrary convention that we set the origin to 0.

In other words: to the extent that your arguments that zero-vectors are 
special are correct, the same applies to zero-points, since vectors are 
defined as a magnitude and direction *from the origin*.

To put it yet another way:

The complex number a+bj is equivalent to the 2D point (a, b) which is 
equivalent to the 2D vector [a, b]. If (0, 0) shouldn't be considered 
falsey, neither should [0, 0].


> The significance of zero in real algebra is not that it is the origin
> but rather that it is the additive and multiplicative zero:
> 
>a + 0 = a  for any real number a
>a * 0 = 0 for any real number a

I'm not sure what you mean by "additive and multiplicative zero", you 
appear to be conflating two different properties here. 0 is the additive 
*identity*, but 1 is the multiplicative identity:

a + 0 = a
a * 1 = a
for any real number a.

If the RHS must be zero, then there is a unique multiplicative zero, but 
no unique additive zero:

a * 0 = 0 for any real number a
a + -a = 0 for any real number a


> The same is true for a vector v0, of length 0:
> 
>v + v0 = v for any vector v
>a * v0 = v0 for any scalar a

Well that's a bogus analogy. Since you're talking about the domain of 
vectors, the relevant identify for the second line should be:

v * v0 = v0 for any vector v

except that doesn't work, since vector algebra doesn't define a vector 
multiplication operator.[1] It does define multiplication between a 
vector and a scalar, which represents a scale transformation.


> There is however no meaningful sense in which points (as opposed to
> vectors) can be added to each other or multiplied by anything, so there
> is no zero point.

I think that the great mathematician Carl Gauss would have something to 
say about that.

Points in the plane are equivalent to complex numbers, and you can 
certainly add and multiply complex numbers. Adding two points is 
equivalent to a translation; multiplication of a scalar with a point is 
equivalent to a scale transformation. Multiplying two points is 
equivalent to complex multiplication, which is a scale + a rotation.

Oh look, that's exactly the same geometric interpretation as for vectors. 
H

Re: List comprehension for testing **params

2012-11-11 Thread Ian Kelly
On Sun, Nov 11, 2012 at 3:24 PM, Cantabile  wrote:
> I'd like to do something like that instead of the 'for' loop in __init__:
>
> assert[key for key in required if key in params.keys()]

A list evaluates as true if it is not empty.  As long as at least one
of the required parameters is present, the list will not be empty and
will evaluate as true, and the assertion will pass.  Try this instead:

assert all(key in params.keys() for key in required)

By the way, using assertions for input checking is generally not
considered good practice.  As soon as Python is invoked with the -O
option, your input testing is tossed out the window.  Assertions are
good to use for internal logic testing, to avoid unexpected state.
For input checking, use an explicit if test and exception:

if any(key not in params.keys() for key in required):
raise ValueError("Missing required keyword argument")

Additionally, if the arguments are required, then they probably have
no business being wrapped up in **params in the first place.  Why not
just define your method like:

def __init__(self, smtp, login, subject, from, to, msg):
# ...

And then Python will do all the work of requiring them to be present for you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: List comprehension for testing **params

2012-11-11 Thread Tim Chase
> assert[key for key in required if key in params.keys()]
...
> Could you explain why it doesn't work and do you have any idea of how it 
> could work ?

Well, here, if any of the items are found, you get a list that is
non-False'ish, so the assert passes.

It sounds like you want all() (available as of 2.5)

  assert all(key in params for key in required)

This is modulo any key normalization for "From" vs. "FROM" vs.
"from", etc; but should be enough to pass your initial requirements.

-tkc


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


Re: List comprehension for testing **params

2012-11-11 Thread Steven D'Aprano
On Sun, 11 Nov 2012 23:24:14 +0100, Cantabile wrote:

> Hi,
> I'm writing a small mail library for my own use, and at the time I'm
> testing parameters like this:
> 
> class Mail(object):
>  def __init__(self, smtp, login, **params)
>  blah
>  blah
>  required = ['Subject', 'From', 'To', 'msg'] for i in required:
>  if not i in params.keys():
>  print "Error, \'%s\' argument is missing" %i exit(1)
>  ...

Eeek! Don't do that. Seriously dude, that is Evil. Why should a simple 
missing argument to a class *kill the entire application*

How horrible would it be if you called "chr()" and instead of raising a 
TypeError, Python shut down? Don't do that. Raise a proper exception. 
Then you have the choice to either catch the exception and continue, or 
let it propagate as appropriate.


But you shouldn't even be manually checking for required arguments. Just 
use real arguments:

def __init__(self, smpt, login, Subject, From, To, msg, **params):
blah 


See how easy it is? Problem solved. If you don't provide an argument, 
Python gives you an exception for free. Best of all, you can use 
inspection to see what arguments are required, and help(Mail) shows you 
what arguments are needed.

You can still use **md as below, and Python will automatically do 
everything you're manually trying to do (and failing). Don't fight the 
language, even when you win, you lose.


> md = {'Subject' : 'Test', 'From' :'Me', 'To' :['You', 'Them'], 'msg'
> :my.txt"}
> 
> m = Mail('smtp.myprovider.com', ["mylogin", "mypasswd"], **md)

Conventionally, a tuple ("mylogin", "mypasswd") would express the intent 
better than a list.


> I'd like to do something like that instead of the 'for' loop in
> __init__:
> 
> assert[key for key in required if key in params.keys()]
> 
> but it doesn't work. It doesn't find anythin wrong if remove, say msg,
> from **md. I thought it should because I believed that this list
> comprehension would check that every keyword in required would have a
> match in params.keys.

No, you have three problems there.

The first problem is that only the empty list is falsey:

assert []  # this raises an exception
assert ["Subject", "From"]  # this doesn't, even though "To" and "msg" 
are missing.

You could say:

assert all([key in params for key in required])

but that leaves you with the next two problems:

2) Fixing the assert still leaves you with the wrong exception. You 
wouldn't raise a ZeroDivisionError, or a UnicodeDecodeError, or an IOError 
would you? No of course not. So why are you suggesting raising an 
AssertionError? That is completely inappropriate, the right exception to 
use is TypeError. Don't be lazy and treat assert as a quick and easy way 
to get exceptions for free.

3) Asserts are not guaranteed to run. Never, never, never use assert to 
test function arguments supplied by the caller, because you have no 
control over whether or not the asserts will even be called.

The whole point of assertions is that the caller can disable them for 
speed. Asserts should be used for testing your code's internal logic, not 
user-provided arguments. Or for testing things which "can't possibly 
fail". But of course, since what can't go wrong does, you sometimes still 
want to test things.

If you've ever written something like:

if condition:
process()
else:
# this cannot happen, but just in case!
print "something unexpected went wrong!"


that's a perfect candidate for an assertion:

assert condition, "something unexpected went wrong!"
process()



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


Re: List comprehension for testing **params

2012-11-11 Thread Terry Reedy

On 11/11/2012 5:56 PM, Ian Kelly wrote:

On Sun, Nov 11, 2012 at 3:24 PM, Cantabile  wrote:

I'd like to do something like that instead of the 'for' loop in __init__:

assert[key for key in required if key in params.keys()]


A list evaluates as true if it is not empty.  As long as at least one
of the required parameters is present, the list will not be empty and
will evaluate as true, and the assertion will pass.  Try this instead:

assert all(key in params.keys() for key in required)

By the way, using assertions for input checking is generally not
considered good practice.   As soon as Python is invoked with the -O
option, your input testing is tossed out the window.  Assertions are
good to use for internal logic testing, to avoid unexpected state.
For input checking, use an explicit if test and exception:

if any(key not in params.keys() for key in required):
 raise ValueError("Missing required keyword argument")

Additionally, if the arguments are required, then they probably have
no business being wrapped up in **params in the first place.  Why not
just define your method like:

def __init__(self, smtp, login, subject, from, to, msg):


or if you want them to be identified by keyword only (since 7 positional 
args is a bit much)


def __init__(self, smtp, login, *, subject, from, to, msg):

(I forget when this feature was added)



 # ...

And then Python will do all the work of requiring them to be present for you.




--
Terry Jan Reedy

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


Re: List comprehension for testing **params

2012-11-11 Thread Steven D'Aprano
On Sun, 11 Nov 2012 18:37:05 -0500, Terry Reedy wrote:

> or if you want them to be identified by keyword only (since 7 positional
> args is a bit much)
> 
> def __init__(self, smtp, login, *, subject, from, to, msg):
> 
> (I forget when this feature was added)

It's a Python 3 feature.



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


Re: List comprehension for testing **params

2012-11-11 Thread Cantabile

Thanks everyone for your answers. That's much clearer now.
I see that I was somehow fighting python instead of using it. Lesson 
learned (for the time being at least) :)

I'll probably get back with more questions...
Cheers,
Cantabile

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


writing a csv file

2012-11-11 Thread ejsaiet
Hello,
I have the script below, which it extracts NOAA data from HTML and is planed 
writes it to a CSV file. Here is the script:

import urllib2
from bs4 import BeautifulSoup
from time import localtime, strftime
import csv

#This script is intended to retrive NOAA data and apend it to a csv file.

# Wait 45 min
#Need to work on this part...


# Go into URL
page = urllib2.urlopen("http://w1.weather.gov/obhistory/PAFA.html";)
soup = BeautifulSoup(page)
datemonth=strftime("%m", localtime())
dateday=strftime("%d", localtime())



with open("/home/eyalak/Documents/weather/weather.csv", "wb") as f:
  writer = csv.writer(f)
  table = soup.findAll("table")[3]
  #print table
  for tr in table.findAll("tr", valign="top"):
 a={x.string for x in tr.findAll('td')}
 print str(a)
 writer.writerows([a])

It did not work unless I changed the line a={x.string for x in 
tr.findAll('td')} to a=list({x.string for x in tr.findAll('td')})

But that disorganizes the data. How can I write the data to a csv file without 
altering the order prior to the list function.
Thanks
E
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: List comprehension for testing **params

2012-11-11 Thread Tim Chase
On 11/11/12 17:18, Steven D'Aprano wrote:
> but that leaves you with the next two problems:
> 
> 2) Fixing the assert still leaves you with the wrong exception. You 
> wouldn't raise a ZeroDivisionError, or a UnicodeDecodeError, or an IOError 
> would you? No of course not. So why are you suggesting raising an 
> AssertionError? That is completely inappropriate, the right exception to 
> use is TypeError. Don't be lazy and treat assert as a quick and easy way 
> to get exceptions for free.

I'd say that it depends on whether the dictionary/kwargs gets
populated from user-supplied data (whether mail, a file, direct
input, etc), or whether it's coder-supplied.

I like to think of "assert" as a "hey, you bone-headed programmer,
you did something that violated conditions for using this code
properly!" and as such, entirely appropriate to use in the
coder-supplied case.  This rolls into...

> 3) Asserts are not guaranteed to run. Never, never, never use assert to 
> test function arguments supplied by the caller, because you have no 
> control over whether or not the asserts will even be called.

where, once the programmer is satisfied that the code runs, meeting
all the appropriate tests/assertions, the assertions can then be
turned off (if one really cares that much; can't say I've done it
more than a couple times, mostly out of experimentation/testing to
see if it made any grave difference in performance).  I think you
intend this in your

> Or for testing things which "can't possibly fail". But of
> course, since what can't go wrong does, you sometimes still want
> to test things.

-tkc



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


Re: writing a csv file

2012-11-11 Thread Mark Lawrence

On 12/11/2012 00:05, ejsa...@alaska.edu wrote:


with open("/home/eyalak/Documents/weather/weather.csv", "wb") as f:
   writer = csv.writer(f)
   table = soup.findAll("table")[3]
   #print table
   for tr in table.findAll("tr", valign="top"):
  a={x.string for x in tr.findAll('td')}
  print str(a)
  writer.writerows([a])

It did not work unless I changed the line a={x.string for x in 
tr.findAll('td')} to a=list({x.string for x in tr.findAll('td')})

But that disorganizes the data. How can I write the data to a csv file without 
altering the order prior to the list function.
Thanks
E



Change the line print str(a) to print type(a), a
You'll see what the problem is and be able to fix it.

--
Cheers.

Mark Lawrence.

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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Oscar Benjamin
On 11 November 2012 22:31, Steven D'Aprano
 wrote:
> On Sun, 11 Nov 2012 14:21:19 +, Oscar Benjamin wrote:
>
>> On 11 November 2012 02:47, Chris Angelico  wrote:
>>> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly 
>>> wrote:
 On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico 
 wrote:
> I would not assume that. The origin is a point, just like any other.
> With a Line class, you could deem a zero-length line to be like a
> zero-element list, but Point(0,0) is more like the tuple (0,0) which
> is definitely True.
 It's more like the number 0 than the tuple (0,0).

 0 is the origin on a 1-dimensional number line. (0,0) is the origin on
 a 2-dimensional number plane.

 In fact, it might be pointed out that Point(0, 0) is a generalization
 of 0+0j, which is equal to 0.
>>>
>>> Ah, good point. In any case, though, it'd be an utterly inconsequential
>>> bug.
>>
>> You were right the first time, Chris. A point that happens to coincide
>> with the arbitrarily chosen origin is no more truthy or falsey than any
>> other. A vector of length 0 on the other hand is a very different beast.
>
> Nonsense. The length and direction of a vector is relative to the origin.
> If the origin is arbitrary, as you claim, then so is the length of the
> vector.

Wrong on all counts. Neither the length not the direction os a vector
are relative to any origin. When we choose to express a vector in
Cartesian components our representation assumes an orientation for the
axes of the coordinate system. Even in this sense, though, the origin
itself does not affect the components of the vector.

I have spent a fair few hours in the past few weeks persuading
teenaged Engineering students to maintain a clear distinction between
points, vectors and lines. One of the ways that I distinguish vectors
from points is to say that a vector is like an arrow but its base has
no particular position. A point on the other hand is quite simply a
position. Given an origin (an arbitrarily chosen point) we can specify
another point using a "position vector": a vector from the origin to
the point in question.

> Just because we can perform vector transformations on the plane to move
> the origin to some point other that (0,0) doesn't make (0,0) an
> "arbitrarily chosen origin". It is no more arbitrary than 0 as the origin
> of the real number line.

(0, 0) are the coordinates of the origin *relative to itself*. Had we
chosen a different origin, the point that was previously called (0, 0)
would now be called (a, b) for some other numbers a and b.

> And yes, we can perform 1D vector transformations on the real number line
> too. Here's a version of range that sets the origin to 42, not 0:
>
> def myrange(start, end=None, step=1):
> if end is None:
> start = 42
> return range(start, end, step)

This is lost on me...

> Nevertheless, there really is something special about the point 0 on the
> real number line

Agreed.

> , the point (0,0) on the complex number plane,

Also agreed.

> the point
> (0,0,0) in the 3D space, (0,0,0,0) in 4D space, etc. It is not just an
> arbitrary convention that we set the origin to 0.

Wrong. The point (0,0,0,...) in some ND space is an arbitrarily chosen
position. By this I don't mean to say that the sequence of coordinates
consisting of all zeros is arbitrary. The choice of the point *in the
real/hypothetical space* that is designated by the sequence of zero
coordinates is arbitrary.

> In other words: to the extent that your arguments that zero-vectors are
> special are correct, the same applies to zero-points, since vectors are
> defined as a magnitude and direction *from the origin*.

Plain wrong. Vectors are not defined *from any origin*.

> To put it yet another way:
>
> The complex number a+bj is equivalent to the 2D point (a, b) which is
> equivalent to the 2D vector [a, b]. If (0, 0) shouldn't be considered
> falsey, neither should [0, 0].

a+bj is not equivalent to the 2D point (a, b). It is possible to
define a mapping between complex numbers and a 2D space so that a+bj
corresponds to the point (a, b) *under that map*. However there are an
infinite number of such possible mappings between the two spaces
including a+bj -> (a+1, b+1).

>> The significance of zero in real algebra is not that it is the origin
>> but rather that it is the additive and multiplicative zero:
>>
>>a + 0 = a  for any real number a
>>a * 0 = 0 for any real number a
>
> I'm not sure what you mean by "additive and multiplicative zero", you
> appear to be conflating two different properties here. 0 is the additive
> *identity*, but 1 is the multiplicative identity:

I mean that it has the properties that zero has when used in addition
and multiplication:
http://en.wikipedia.org/wiki/0_%28number%29#Elementary_algebra

>
> a + 0 = a
> a * 1 = a
> for any real number a.

No. I meant the two properties that I listed.

>
> If the RHS must be zero, then there is a unique multiplicative

Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Steve Howell
On Nov 10, 11:33 am, Jennie  wrote:
> What is the best solution to solve the following problem in Python 3.3?
>
> import math
>  >>> class Point:
> ...     def __init__(self, x=0, y=0):
> ...         self.x = x
> ...         self.y = y
> ...     def __sub__(self, other):
> ...         return Point(self.x - other.x, self.y - other.y)
> ...     def distance(self, point=Point()):
> ...         """Return the distance from `point`."""
> ...         return math.sqrt((self - point).x ** 2 + (self - point).y ** 2)

Before you do anything else, introduce a Vector class into your app.
The difference between two Points is not a Point; it's a Vector.
Create a magnitude() method in your Vector class, then make your
Point.distance return the results of Vector.magnitude(self - other).
To define the distance of a point from the origin, don't make your
distance() method have default arguments; instead, define another
method called distance_from_origin().

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


Re: A gnarly little python loop

2012-11-11 Thread Cameron Simpson
On 11Nov2012 11:16, Steve Howell  wrote:
| On Nov 11, 10:34 am, Peter Otten <__pete...@web.de> wrote:
| > Steve Howell wrote:
| > > On Nov 11, 1:09 am, Paul Rubin  wrote:
| > >> Cameron Simpson  writes:
| > >> > | I'd prefer the original code ten times over this inaccessible beast.
| > >> > Me too.
| >
| > >> Me, I like the itertools version better.  There's one chunk of data
| > >> that goes through a succession of transforms each of which
| > >> is very straightforward.
| >
| > > Thanks, Paul.
| >
| > > Even though I supplied the "inaccessible" itertools version, I can
| > > understand why folks find it inaccessible.  As I said to the OP, there
| > > was nothing wrong with the original imperative approach; I was simply
| > > providing an alternative.
| >
| > > It took me a while to appreciate itertools, but the metaphor that
| > > resonates with me is a Unix pipeline.
[...]
| > Actually you supplied the "accessible" itertools version. For reference,
| > here's the inaccessible version:
[...]
| I know Peter's version is tongue in cheek, but I do think that it has
| a certain expressive power, and it highlights three mind-expanding
| Python modules.
| Here's a re-flattened take on Peter's version ("Flat is better than
| nested." -- PEP 20):
[...]

Ok, who's going to quiz the OP on his/her uptake of these techniques...
-- 
Cameron Simpson 

It's hard to make a man understand something when his livelihood depends
on him not understanding it. - Upton Sinclair
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Steve Howell
On Nov 11, 4:31 pm, Oscar Benjamin  wrote:
> On 11 November 2012 22:31, Steven D'Aprano

> > Nonsense. The length and direction of a vector is relative to the origin.
> > If the origin is arbitrary, as you claim, then so is the length of the
> > vector.
>
> Wrong on all counts. Neither the length not the direction os a vector
> are relative to any origin. When we choose to express a vector in
> Cartesian components our representation assumes an orientation for the
> axes of the coordinate system. Even in this sense, though, the origin
> itself does not affect the components of the vector.
>

Thank you for pushing back on Steven's imprecise statement that the
"direction of a vector is relative to the origin."

You can't find an angle between two points.  That's absurd.  You need
axes for context.


> Vectors, points and complex numbers are not equivalent. There are
> cases in which it is reasonable to think of them as equivalent for a
> particular purpose. That does not diminish the fundamental differences
> between them.
>

I looked to wikipedia for clarity, but the definition of a Euclidean
vector is somewhat muddy:

http://en.wikipedia.org/wiki/Euclidean_vector

They say that the formal definition of a vector is a directed line
segment.  But then they define a "free vector" as an entity where only
the magnitude and direction matter, not the initial point.

As you say, it's not unreasonable to treat vectors, points, and
complex numbers as equivalent in many circumstances.  But, if you're
gonna be pedantic, they really are different things.

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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Mark Lawrence

On 12/11/2012 00:31, Oscar Benjamin wrote:


Plain wrong. Vectors are not defined *from any origin*.



So when the Captain says "full speed ahead, steer 245 degrees", you 
haven't the faintest idea where you're going, because you have no origin?


--
Cheers.

Mark Lawrence.

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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Oscar Benjamin
On 12 November 2012 01:10, Mark Lawrence  wrote:
> On 12/11/2012 00:31, Oscar Benjamin wrote:
>>
>>
>> Plain wrong. Vectors are not defined *from any origin*.
>>
>
> So when the Captain says "full speed ahead, steer 245 degrees", you haven't
> the faintest idea where you're going, because you have no origin?

As Steve has just explained, the origin has nothing to do with the
orientation of the coordinate system.

But then I'm assuming you meant that 245 degrees was a bearing
relative to North. Was it supposed to be relative to my current angle?
Truthfully I wouldn't know what to do without asking the captain a
couple more questions.


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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Roy Smith
In article ,
 Mark Lawrence  wrote:

> On 12/11/2012 00:31, Oscar Benjamin wrote:
> >
> > Plain wrong. Vectors are not defined *from any origin*.
> >
> 
> So when the Captain says "full speed ahead, steer 245 degrees", you 
> haven't the faintest idea where you're going, because you have no origin?

Vectors have a length ("full speed ahead") and a direction ("245 
degrees").  What they don't have is a fixed location in space.  The 
captain didn't say, "Full speed ahead, steer 245 degrees, from 45.0N, 
20.0W".

In other words, you are correct.  The order, "full speed ahead, steer 
245 degrees", doesn't give you the faintest idea of where you're going.  
If you were the helmsman, after you executed that order, without any 
additional information (such as your current location), you would have 
no idea what piece of land you will hit, or when you will hit it, if you 
maintain your current course and speed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Mark Lawrence

On 12/11/2012 01:18, Oscar Benjamin wrote:

On 12 November 2012 01:10, Mark Lawrence  wrote:

On 12/11/2012 00:31, Oscar Benjamin wrote:



Plain wrong. Vectors are not defined *from any origin*.



So when the Captain says "full speed ahead, steer 245 degrees", you haven't
the faintest idea where you're going, because you have no origin?


As Steve has just explained, the origin has nothing to do with the
orientation of the coordinate system.

But then I'm assuming you meant that 245 degrees was a bearing
relative to North. Was it supposed to be relative to my current angle?
Truthfully I wouldn't know what to do without asking the captain a
couple more questions.


Oscar



The only good acedemic is a dead acedemic?

--
Cheers.

Mark Lawrence.

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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Mark Lawrence

On 12/11/2012 01:15, Roy Smith wrote:

In article ,
  Mark Lawrence  wrote:


On 12/11/2012 00:31, Oscar Benjamin wrote:


Plain wrong. Vectors are not defined *from any origin*.



So when the Captain says "full speed ahead, steer 245 degrees", you
haven't the faintest idea where you're going, because you have no origin?


Vectors have a length ("full speed ahead") and a direction ("245
degrees").  What they don't have is a fixed location in space.  The
captain didn't say, "Full speed ahead, steer 245 degrees, from 45.0N,
20.0W".

In other words, you are correct.  The order, "full speed ahead, steer
245 degrees", doesn't give you the faintest idea of where you're going.
If you were the helmsman, after you executed that order, without any
additional information (such as your current location), you would have
no idea what piece of land you will hit, or when you will hit it, if you
maintain your current course and speed.



Thank you for your explanation.

--
Cheers.

Mark Lawrence.

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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Roy Smith
In article ,
 Oscar Benjamin  wrote:

> But then I'm assuming you meant that 245 degrees was a bearing
> relative to North. Was it supposed to be relative to my current angle?
> Truthfully I wouldn't know what to do without asking the captain a
> couple more questions.

Granted, this requires some domain-specific knowledge, but an order to 
"steer 245 degrees" means relative to north (and, technically, it's a 
heading, not a bearing, but that's another discussion).

If the captain wanted you to change you heading relative to your current 
heading, he would say something like, "turn left 10 degrees" (that may 
not be strictly the correct wording).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A gnarly little python loop

2012-11-11 Thread Steve Howell
On Nov 11, 4:44 pm, Cameron Simpson  wrote:
> On 11Nov2012 11:16, Steve Howell  wrote:
> | On Nov 11, 10:34 am, Peter Otten <__pete...@web.de> wrote:
> | > Steve Howell wrote:
> | > > On Nov 11, 1:09 am, Paul Rubin  wrote:
> | > >> Cameron Simpson  writes:
> | > >> > | I'd prefer the original code ten times over this inaccessible 
> beast.
> | > >> > Me too.
> | >
> | > >> Me, I like the itertools version better.  There's one chunk of data
> | > >> that goes through a succession of transforms each of which
> | > >> is very straightforward.
> | >
> | > > Thanks, Paul.
> | >
> | > > Even though I supplied the "inaccessible" itertools version, I can
> | > > understand why folks find it inaccessible.  As I said to the OP, there
> | > > was nothing wrong with the original imperative approach; I was simply
> | > > providing an alternative.
> | >
> | > > It took me a while to appreciate itertools, but the metaphor that
> | > > resonates with me is a Unix pipeline.
> [...]
> | > Actually you supplied the "accessible" itertools version. For reference,
> | > here's the inaccessible version:
> [...]
> | I know Peter's version is tongue in cheek, but I do think that it has
> | a certain expressive power, and it highlights three mind-expanding
> | Python modules.
> | Here's a re-flattened take on Peter's version ("Flat is better than
> | nested." -- PEP 20):
> [...]
>
> Ok, who's going to quiz the OP on his/her uptake of these techniques...

Cameron, with all due respect, I think you're missing the point.

Roy posted this code:

page = 1
while 1:
r = api.GetSearch(term="foo", page=page)
if not r:
break
for tweet in r:
process(tweet)
page += 1

In his own words, he described the loop as "gnarly" and the overall
code as "fidgety."

One way to eliminate the "while", the "if", and the "break" statements
is to use higher level constructs that are shipped with all modern
versions of Python, and which are well documented and well tested (and
fast, I might add):

search = partial(api.GetSearch, "foo")
paged_tweets = imap(search, count(1))
paged_tweets = takewhile(bool, paged_tweets)
tweets = chain.from_iterable(paged_tweets)
for tweet in tweets:
process(tweet)

The moral of the story is that you can avoid brittle loops by relying
on a well-tested library to work at a higher level of abstraction.

For this particular use case, the imperative version is fine, but for
more complex use cases, the loops are only gonna get more gnarly and
fidgety.



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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Oscar Benjamin
On 12 November 2012 01:29, Mark Lawrence  wrote:
> On 12/11/2012 01:18, Oscar Benjamin wrote:
>>
>> On 12 November 2012 01:10, Mark Lawrence  wrote:
>>>
>>> On 12/11/2012 00:31, Oscar Benjamin wrote:

 Plain wrong. Vectors are not defined *from any origin*.
>>>
>>> So when the Captain says "full speed ahead, steer 245 degrees", you
>>> haven't
>>> the faintest idea where you're going, because you have no origin?
>>
>>
>> As Steve has just explained, the origin has nothing to do with the
>> orientation of the coordinate system.
>>
>> But then I'm assuming you meant that 245 degrees was a bearing
>> relative to North. Was it supposed to be relative to my current angle?
>> Truthfully I wouldn't know what to do without asking the captain a
>> couple more questions.
>
> The only good acedemic is a dead acedemic?

Is that what happens when people ask questions on your ship: "it's the
plank for him with the questions-askin'!"

I'm glad you're not my captain.


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


Re: Method default argument whose type is the class not yet defined

2012-11-11 Thread Steven D'Aprano
On Mon, 12 Nov 2012 00:31:53 +, Oscar Benjamin wrote:

[...]
>>> You were right the first time, Chris. A point that happens to coincide
>>> with the arbitrarily chosen origin is no more truthy or falsey than
>>> any other. A vector of length 0 on the other hand is a very different
>>> beast.
>>
>> Nonsense. The length and direction of a vector is relative to the
>> origin. If the origin is arbitrary, as you claim, then so is the length
>> of the vector.
> 
> Wrong on all counts. Neither the length not the direction os a vector
> are relative to any origin. When we choose to express a vector in
> Cartesian components our representation assumes an orientation for the
> axes of the coordinate system. Even in this sense, though, the origin
> itself does not affect the components of the vector.


Draw a set of axes and mark the vector [1, 1]. Here's a crappy ASCII art 
diagram, with X marking the head of the vector and a line drawn from the 
origin to the head.

|
|   X
|  /
| /
|/
+--


Now draw a second set of axes with the origin set at the head of that 
vector. For reference, I leave the previous axis in place. As before, X 
represents the head of the vector.


|   |
X-
|   |
|   |
|   |
+---|--


Note that the "body" of the vector -- the line from the origin to the 
head -- is gone. That's because the vector [1, 1] is transformed to the 
vector [0, 0] under a translation of one unit in both the X and Y 
directions. The magnitude of the vector under one coordinate system is 1, 
under the second it is 0.

In a nutshell, you can't talk about either *distance* (magnitude) or 
*direction* without an answer to "distance from where? direction relative 
to what?".


> I have spent a fair few hours in the past few weeks persuading teenaged
> Engineering students to maintain a clear distinction between points,
> vectors and lines. One of the ways that I distinguish vectors from
> points is to say that a vector is like an arrow but its base has no
> particular position. A point on the other hand is quite simply a
> position. Given an origin (an arbitrarily chosen point) we can specify
> another point using a "position vector": a vector from the origin to the
> point in question.

Just because you have spent a lot of time and effort giving people advice 
doesn't make it *good* advice.



[...]
> Wrong. The point (0,0,0,...) in some ND space is an arbitrarily chosen
> position. By this I don't mean to say that the sequence of coordinates
> consisting of all zeros is arbitrary. The choice of the point *in the
> real/hypothetical space* that is designated by the sequence of zero
> coordinates is arbitrary.

So what? All you are saying is that there is more than one coordinate 
system, and we can choose the one we like for any problem. Of course we 
can, and that's a good thing.



>>> The significance of zero in real algebra is not that it is the origin
>>> but rather that it is the additive and multiplicative zero:
>>>
>>>a + 0 = a  for any real number a
>>>a * 0 = 0 for any real number a
>>
>> I'm not sure what you mean by "additive and multiplicative zero", you
>> appear to be conflating two different properties here. 0 is the
>> additive *identity*, but 1 is the multiplicative identity:
> 
> I mean that it has the properties that zero has when used in addition
> and multiplication:
> http://en.wikipedia.org/wiki/0_%28number%29#Elementary_algebra

I see no reference to "additive and multiplicative zero" there. Did you 
make up that terminology? The *identity* element is a common mathematical 
term, but 1 is the multiplicative identity element.

What you are describing is generally known as the "absorbing element" 
over multiplication: if X*a = X for any a, then X is an absorbing element 
under multiplication.

http://en.wikipedia.org/wiki/Absorbing_element


And by the way, the vector [0, 0] (generalised to however many dimensions 
you need) is not necessarily the only null (zero) vector. Some vector 
spaces have many null vectors with non-zero components.

http://en.wikipedia.org/wiki/Zero_vector

but I digress.

The exact terminology doesn't really change anything, since everything 
you say about vector [0,0] applies equally to the point (0,0) in the 
Cartesian plane.



[...]
>>> There is however no meaningful sense in which points (as opposed to
>>> vectors) can be added to each other or multiplied by anything, so
>>> there is no zero point.
>>
>> I think that the great mathematician Carl Gauss would have something to
>> say about that.
> 
> Is the text below a quote?

No.
 
>> Points in the plane are equivalent to complex numbers, and you can
>> certainly add and multiply complex numbers. Adding two points is
>> equivalent to a translation; multiplication of a scalar with a point is
>> equivalent to a scale transformation. Multiplying two points is
>> equivalent to complex multiplication, which is a scale + a rotation.
> 
> The last point is bizarre. Complex multiplication makes no sense w

Re: A gnarly little python loop

2012-11-11 Thread rusi
On Nov 11, 3:58 am, Roy Smith  wrote:
> I'm trying to pull down tweets with one of the many twitter APIs.  The
> particular one I'm using (python-twitter), has a call:
>
> data = api.GetSearch(term="foo", page=page)
>
> The way it works, you start with page=1.  It returns a list of tweets.
> If the list is empty, there are no more tweets.  If the list is not
> empty, you can try to get more tweets by asking for page=2, page=3, etc.
> I've got:
>
>     page = 1
>     while 1:
>         r = api.GetSearch(term="foo", page=page)
>         if not r:
>             break
>         for tweet in r:
>             process(tweet)
>         page += 1
>
> It works, but it seems excessively fidgety.  Is there some cleaner way
> to refactor this?

This is a classic problem -- structure clash of parallel loops -- nd
Steve Howell has given the classic solution using the fact that
generators in python simulate/implement lazy lists.
As David Beazley http://www.dabeaz.com/coroutines/ explains,
coroutines are more general than generators and you can use those if
you prefer.

The classic problem used to be stated like this:
There is an input in cards of 80 columns.
It needs to be copied onto printer of 132 columns.

The structure clash arises because after reading 80 chars a new card
has to be read; after printing 132 chars a linefeed has to be given.

To pythonize the problem, lets replace the 80,132 by 3,4, ie take the
char-square
abc
def
ghi

and produce
abcd
efgh
i

The important difference (explained nicely by Beazley) is that in
generators the for-loop pulls the generators, in coroutines, the
'generator' pushes the consuming coroutines.


---
from __future__ import print_function
s= ["abc", "def", "ghi"]

# Coroutine-infrastructure from pep 342
def consumer(func):
def wrapper(*args,**kw):
gen = func(*args, **kw)
gen.next()
return gen
return wrapper

@consumer
def endStage():
while True:
for i in range(0,4):
print((yield), sep='', end='')
print("\n", sep='', end='')


def genStage(s, target):
for line in s:
for i in range(0,3):
target.send(line[i])


if __name__ == '__main__':
genStage(s, endStage())






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


Re: List comprehension for testing **params

2012-11-11 Thread Steven D'Aprano
On Sun, 11 Nov 2012 18:21:32 -0600, Tim Chase wrote:

> On 11/11/12 17:18, Steven D'Aprano wrote:
>> but that leaves you with the next two problems:
>> 
>> 2) Fixing the assert still leaves you with the wrong exception. You
>> wouldn't raise a ZeroDivisionError, or a UnicodeDecodeError, or an
>> IOError would you? No of course not. So why are you suggesting raising
>> an AssertionError? That is completely inappropriate, the right
>> exception to use is TypeError. Don't be lazy and treat assert as a
>> quick and easy way to get exceptions for free.
> 
> I'd say that it depends on whether the dictionary/kwargs gets populated
> from user-supplied data (whether mail, a file, direct input, etc), or
> whether it's coder-supplied.

No, it doesn't matter if it is end-user supplied or coder-supplied. As 
usual, look at the standard library and Python builtins for best 
practices:

py> len(42)  # do we get an AssertionError?
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'int' has no len()



> I like to think of "assert" as a "hey, you bone-headed programmer, you
> did something that violated conditions for using this code properly!"

You mean like passing a list to ord()? Or trying to add a number and a 
string?

Raise the appropriate exception for the error: TypeError for type errors 
and missing function parameters, ValueErrors for objects of the right 
type but a bad argument, etc. Assertion errors are for asserting facts 
about internal program logic. "I assert that such-and-such is a fact", 
rather than "I require that such-and-such is a fact".

For example, this might be a reasonable (although trivial) use of assert:

def spam(n):
if isinstance(n, int) and n > 0:
result = ' '.join(["spam"]*n)
assert result, "expected non-empty string but got empty"
return result
else:
raise SpamError("No spam for you!!!")

This gives a measure of protection against logic errors such as writing 
n >= 0.

The presence of the assert is partly documentation and partly error 
checking, but the important thing is that it checks things which depend 
on the internal logic of the code itself, not on the input to the code. 
Given that you have already explicitly tested that n > 0, then the 
logical consequence is that "spam"*n will be non-empty. Hence an 
assertion "I assert that the string is not empty", rather than an overt 
test "Is the string empty?"

Now, I accept that sometimes it is hard to draw a line between "internal 
program logic" and external input. E.g. if one function generates a value 
x, then calls another function with x as argument, the state of x is an 
internal detail to the first function and an external input to the other 
function. The rules I use are:

* If the argument is a public parameter to a public function, 
  then you must not use assert to validate it;

* If the argument is a private parameter, or if the function 
  is a private function, then you may use assert to validate
  it (but probably shouldn't);

* You can use assert to check conditions of function internal
  variables (locals that you control);

* Once you cross the boundary to another function, your objects
  should be treated as external again.

E.g. I might have:

def foo(a, b):
# foo, a and b are public, so don't use assert
if not (isinstance(a, int) and isinstance(b, int)):
raise TypeError
x = abs(a) + abs(b)
# x is purely internal, so okay to assert
assert x >= 0, "Hey McFly, you screwed up!"
return bar(x)

def bar(x):
if x <= 0:
raise ValueError("expected positive x")
...

This now guards against something other than foo calling bar.



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