Re: Can't match str/unicode

2017-01-07 Thread CM
On Sunday, January 8, 2017 at 1:17:56 AM UTC-5, Steven D'Aprano wrote:
> On Sunday 08 January 2017 15:33, CM wrote:
> 
> > On Saturday, January 7, 2017 at 7:59:01 PM UTC-5, Steve D'Aprano wrote:
> [...]
> >> Start by printing repr(candidate_text) and see what you really have.
> > 
> > Yes, that did it. The repr of that one was, in fact:
> > 
> > u'match /r'
> 
> Are you sure it is a forward-slash /r rather than backslash \r?

No, you're right, it was a backslash \r. Should have pasted it. Good catch.
-- 
https://mail.python.org/mailman/listinfo/python-list


Grumpy: Python to Go compiler

2017-01-07 Thread Steven D'Aprano
Grumpy, an experimental project from Google, transpiles Python code into Go,
allowing Python programs to be compiled and run as static binaries using the Go
toolchain.



http://www.infoworld.com/article/3154624/application-development/google-boosts-python-by-turning-it-into-go.html


-- 
Steven
"Ever since I learned about confirmation bias, I've been seeing 
it everywhere." - Jon Ronson

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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Jussi Piitulainen
Pablo Lucena writes:

> How about using the second usage of builtin iter()?
>
> In [92]: iter?
> Docstring:
> iter(iterable) -> iterator
> iter(callable, sentinel) -> iterator

Nice to learn about that. But it has the same problem as
itertools.takewhile:

> In [88]: numbers
> Out[88]: [1, 9, 8, 11, 22, 4, 0, 3, 5, 6]
>
> # create iterator over the numbers to make callable simple
> # you may pre-sort or do w/e as needed of course
> In [89]: numbers_it = iter(numbers)
>
> # callable passed into iter - you may customize this
> # using functools.partial if need to add function arguments
> In [90]: def grab_until():
> ...: return next(numbers_it)
> ...:
>
> # here 0 is the 'sentinel' ('int()' would work as well as you have
> # the iterator produced by iter() here stops as soon as sentinel value
> # is encountered
> In [91]: list(iter(grab_until, 0))
> Out[91]: [1, 9, 8, 11, 22, 4]

You get the same with numbers = [1, 9, 8, 11, 22, 4], where 0 does not
occur. How do you then tell which it was?

I think both itertools.takewhile(-, -) and iter(-, -) should have an
option to include the sentinel in their output. Then they could be used
in situations like this.

[The discussion with Rustom about Haskell's lazy evaluation is not
related to this, as far as I can see, so I just snipped it from here.]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Cameron Simpson

On 07Jan2017 22:26, jim  wrote:
You've convinced me.  I will have to buckle down and figure out to use 
virtualenv/venv. I see Chris recommends venv. I read through PEP405 and this 
link https://docs.python.org/3.5/library/venv.html. I don't pretend to fully 
understand it all but it does seem to make a good case for using venv over 
virtualenv.


Note that it recommends:

 python3 -m venv ...options... path/to/env_dir

which makes sure you're getting a venv based on a specific python executable; 
in the case above whatever "python3" runs -- you could invoke a different 
python 3 to use that instead.


It looks like aside from saying "python3 -m venv" instead of "virtualenv" my 
previous example recipe should pretty much work for you.


Good luck.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Using namedtuples field names for column indices in a list of lists

2017-01-07 Thread Steven D'Aprano
On Sunday 08 January 2017 16:39, Deborah Swanson wrote:

> What I've done so far:
> 
> with open('E:\\Coding projects\\Pycharm\\Moving\\Moving 2017 in.csv',
> 'r') as infile:
> ls = list(csv.reader(infile))
> lst = namedtuple('lst', ls[0])
> 
> where 'ls[0]' is the header row of the csv, and it works perfectly well.
> 'lst' is a namedtuple instance with each of the column titles as field
> names.

Are you sure? namedtuple() returns a class, not a list:

py> from collections import namedtuple
py> names = ['A', 'B', 'C']
py> namedtuple('lst', names)


The way namedtuple() is intended to be used is like this:


py> from collections import namedtuple
py> names = ['A', 'B', 'C']
py> Record = namedtuple('Record', names)
py> instance = Record(10, 20, 30)
py> print(instance)
Record(A=10, B=20, C=30)


There is no need to call fget directly to access the individual fields:

py> instance.A
10
py> instance.B
20
py> instance[1]  # indexing works too
20


which is *much* simpler than:

py> Record.A.fget(instance)
10



I think you should be doing something like this:

pathname = 'E:\\Coding projects\\Pycharm\\Moving\\Moving 2017 in.csv'
with open(pathname, 'r') as infile:
rows = list(csv.reader(infile))
Record = namedtuple("Record", rows[0])
for row in rows[1:]:  # skip the first row, the header
row = Record(row)
# process this row...
if row.location == 0:
...

[...]
> But I haven't found a way to assign new values to a list element. using
> namedtuple.fieldname. I think a basic problem is that namedtuples have
> the properties of tuples, and you can't assign to an existing tuple
> because they're immutable.

Indeed. Being tuples, you have to create a new one. You can do it with slicing, 
like ordinary tuples, but that's rather clunky:

py> print(instance)
Record(A=10, B=20, C=30)
py> Record(999, *instance[1:])
Record(A=999, B=20, C=30)


The recommended way is with the _replace method:

py> instance._replace(A=999)
Record(A=999, B=20, C=30)
py> instance._replace(A=999, C=888)
Record(A=999, B=20, C=888)


Note that despite the leading underscore, _replace is *not* a private method of 
the class. It is intentionally documented as public. The leading underscore is 
so that it won't clash with any field names.




-- 
Steven
"Ever since I learned about confirmation bias, I've been seeing 
it everywhere." - Jon Ronson

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


Re: Can't match str/unicode

2017-01-07 Thread Steven D'Aprano
On Sunday 08 January 2017 15:33, CM wrote:

> On Saturday, January 7, 2017 at 7:59:01 PM UTC-5, Steve D'Aprano wrote:
[...]
>> Start by printing repr(candidate_text) and see what you really have.
> 
> Yes, that did it. The repr of that one was, in fact:
> 
> u'match /r'

Are you sure it is a forward-slash /r rather than backslash \r?


> Thanks, that did it. Do you happen to know why that /r was appended to the
> unicode object in this case?

*shrug* 

You're the only one that can answer that, because only you know where the text 
came from. The code you showed:

candidate_text = Paragraph.Range.Text.encode('utf-8')

is a mystery, because we don't know what Paragraph is or where it comes from, 
or what .Range.Text does.

You mention "scraping a Word docx", but we have no idea how you're scraping it. 
If I had to guess, I'd guess:

- you actually mean \r rather than /r;

- paragraphs in Word docs always end with a carriage return \r;

- and whoever typed the paragraph accidentally hit the spacebar after typing 
the word "match".


But its just a guess. For all I know, the software you are using to scrape the 
docx file inserts space/r after everything.



-- 
Steven
"Ever since I learned about confirmation bias, I've been seeing 
it everywhere." - Jon Ronson

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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Jussi Piitulainen
Paul Rubin writes:

> Jussi Piitulainen writes:
>>> Use itertools.takewhile
>> How? It consumes the crucial stop element:
>
> Oh yucch, you're right, it takes it from both sides.  How about this:
>
> from itertools import takewhile, islice
> def minabs(xs):
>   a = iter(xs)
>   m = min(map(abs,takewhile(lambda x: x!=0, a)))
>   z = list(islice(a,1))
>   if z: return 0
>   return m

That would return 0 even when there is no 0 in xs at all.

(It would also return the absolute value, not a value whose absolute
value is minimal, but that is easy to fix.)
-- 
https://mail.python.org/mailman/listinfo/python-list


Using namedtuples field names for column indices in a list of lists

2017-01-07 Thread Deborah Swanson
What I've done so far:

with open('E:\\Coding projects\\Pycharm\\Moving\\Moving 2017 in.csv',
'r') as infile:
ls = list(csv.reader(infile))
lst = namedtuple('lst', ls[0])

where 'ls[0]' is the header row of the csv, and it works perfectly well.
'lst' is a namedtuple instance with each of the column titles as field
names. 

And retrieving values also works:

if len(lst.Location.fget(l)) == 0:
.
.

Using the .fget method for each field name returns the value in the row
and column, here row 'l' and column 'Location'.

So far so good. 'lst.Location.fget(l)' is clunkier than l[lo], but it's
recognizable and it works.

But I haven't found a way to assign new values to a list element. using
namedtuple.fieldname. I think a basic problem is that namedtuples have
the properties of tuples, and you can't assign to an existing tuple
because they're immutable. Also there's the matter of
namedtuple.fieldname being a property and not an index integer, so it
doesn't work if you try to use them as indices.

If I try:

l[lst.Location] = 'xyz' ('l' is a list)

I get: TypeError: list indices must be integers, not property

I'm a little hopeful that namedtuples has a built-in solution. In
addition to the method fget, each field name also has a property fset:

fset = {NoneType}None

But I can't find anything in the documentation that tells what fset is
and how to use it.

Another possibility would be to map index integers to the field names in
the namedtuple, in a way that could be accessed using the namedtuple's
field names. I've looked into using map(), but the documentation is so
sketchy I couldn't see a way to do this from what is given.  And
google's no help. If anyone else has tried to do this, google can't find
it. They don't have a string of words that I could find preloaded into
their "AI" code that will turn up anything close. Most search attempts
just ignored all my search terms except 'namedtuples' and returned
general stuff on namedtuples. I looked through a few of them, but
nothing I looked at gave any useful solution to this problem. 

Anybody know how to use .fset?  Or a way to assign to list locations by
their namedtuples fieldnames and list rows?


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


Re: Can't match str/unicode

2017-01-07 Thread Chris Angelico
On Sun, Jan 8, 2017 at 3:31 PM, CM  wrote:
> On Saturday, January 7, 2017 at 6:42:25 PM UTC-5, Chris Angelico wrote:
>
>> What happens if you print the repr of each string? Or, if one of them
>> truly is a literal, just print the repr of the one you got from
>> win32com.
>>
>> ChrisA
>
> Yes, that did it. The repr of that one was, in fact:
>
> u'match /r'
>
> Thanks!

Are you sure that's what it was? Copy and paste for accuracy.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


What is PyOleMissing object? (win32com)

2017-01-07 Thread CM
Trying to manipulate z-order for MSOffice with win32com and wasn't sure what 
argument was needed. Using help on that ZOrder method gives:

>>>
Help on method ZOrder in module win32com.client.dynamic:

ZOrder(self, ZOrderCmd=) method of 
win32com.client.CDispatch instance


So, what does " mean in this case?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Can't match str/unicode

2017-01-07 Thread CM
On Saturday, January 7, 2017 at 7:59:01 PM UTC-5, Steve D'Aprano wrote:
> On Sun, 8 Jan 2017 08:40 am, CM wrote:
> 
> > So what's going on here? Why isn't a string with the content 'match' equal
> > to another string with the content 'match'?
> 
> You don't know that the content is 'match'. All you know is that when
> printed, it *looks like* 'match'.
> 
> Hint:
> 
> s = 'match '
> print 'match', s  # they look the same
> print 'match' == s  # but they aren't the same
> 
> 
> Start by printing repr(candidate_text) and see what you really have.

Yes, that did it. The repr of that one was, in fact:

u'match /r'

Thanks, that did it. Do you happen to know why that /r was appended to the 
unicode object in this case?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Can't match str/unicode

2017-01-07 Thread CM
On Saturday, January 7, 2017 at 6:42:25 PM UTC-5, Chris Angelico wrote:

> What happens if you print the repr of each string? Or, if one of them
> truly is a literal, just print the repr of the one you got from
> win32com.
> 
> ChrisA

Yes, that did it. The repr of that one was, in fact:

u'match /r'

Thanks!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread jim

On 01/07/2017 08:42 PM, Cameron Simpson wrote:

On 07Jan2017 19:45, jim  wrote:

On 01/07/2017 05:58 PM, Clint Moyer wrote:

So to minimize your issues with installing Python packages, take the
path of least resistance and install through your system repo. And use
Python2 or Python3 explicitly to avoid conflicts.


As I mentioned in another post, most of the more popular modules I had
installed on my old system using pip are available in the repository
and I will use the repository to install them on the new system. I now
understand that using sudo is a bad idea.


Cool.


One question from the earlier post that did not get answered concerned
upgrading a repository installed module with pip.


I would recommend not. As soon as you get there:

 - if the vendor updates it, use apt-get (I know this doesn't fit your
   situation with Ubuntu 16.04 LTS)

 - if you want a more modern version, now is the time to use virtualenv

The thing about LTS is that the vendor guarentees its stability. If you
upgrade the vendor installed package using /usr/bin/pip (or pip3) as
root, you're replacing the vendor supplied module with a newer one,
which may break vendor supplied packages which use that module expected
the _old_ behaviour.

So endeavour to leave the vendor suppplied stuff entirely alone except
for apt-get style updates.

Instead, make a virtualenv an upgrade it with a newer package.


To get started on the new system I installed pip3 from the repository.
The first time I used it to install a module it said a newer version
was available and gave the command to update it. What are the
consequences of using pip to upgrade repository installed modules?


In theory, if the newer version of the module installs a breaking change
it can break things in the system which might use that module and expect
its old behaviour. Also, _sometimes_, vendors supply patches versions of
packages, possibly including python modules. If they're
modified/patched, there is probably a reason. You'd be undoing that patch.


I ask because 16.04 is LTS and won't be getting version upgrades
unless they are security related. Also pandas is in the repositories
but the module pandas-datareader, which I may need to use, is not.


Again: make a virtualenv as yourself.

Its pip can be run as yourself, therefore cannot accidentally modify
system module. It's pip can freely upgrade a older module. If you
install a module _not_ supplied by the vendor, the virtualenv pip can
freely do that, and _also_ upgrade a required module should that be
required (PyPI package definitions let a module specify required
revisions of other modules it may use).

Cheers,
Cameron Simpson 


You've convinced me.  I will have to buckle down and figure out to use 
virtualenv/venv. I see Chris recommends venv. I read through PEP405 and 
this link https://docs.python.org/3.5/library/venv.html. I don't pretend 
to fully understand it all but it does seem to make a good case for 
using venv over virtualenv.


thanks,  Jim



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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Paul Rubin
Jussi Piitulainen  writes:
>> Use itertools.takewhile
> How? It consumes the crucial stop element:

Oh yucch, you're right, it takes it from both sides.  How about this:

from itertools import takewhile, islice
def minabs(xs):
a = iter(xs)
m = min(map(abs,takewhile(lambda x: x!=0, a)))
z = list(islice(a,1))
if z: return 0
return m
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Clint Moyer
I would lightly advise against, assuming both Pip and your package
manager are trying to accomplish nearly the same thing. Stick with
updating through the repo.

If you find that the version your OS provides is out-of-date compared
to what's on PyPi or Github, then you might want to remove from your
OS and re-install through Pip, for those discrete cases. That's the
platform agnostic route.
--
Clint


On Sat, Jan 7, 2017 at 6:45 PM, jim  wrote:
> On 01/07/2017 05:58 PM, Clint Moyer wrote:
>>
>> Not sure how you guys got this thread so far off topic, but I think it
>> is valuable to present the current situation in the context of Jim's
>> sudo question. Staying on topic, the emphasis should be on taking the
>> path of least resistance with your current OS. The only thing to be
>> gleaned from PEP394 is that users should not put faith or expectations
>> in what their /usr/bin/python symlink points to. Most systems point to
>> Python2, but it is not guaranteed.
>>
>> So to minimize your issues with installing Python packages, take the
>> path of least resistance and install through your system repo. And use
>> Python2 or Python3 explicitly to avoid conflicts.
>>
>> --
>> Clint
>>
>
> As I mentioned in another post, most of the more popular modules I had
> installed on my old system using pip are available in the repository and I
> will use the repository to install them on the new system. I now understand
> that using sudo is a bad idea.
>
> One question from the earlier post that did not get answered concerned
> upgrading a repository installed module with pip. To get started on the new
> system I installed pip3 from the repository. The first time I used it to
> install a module it said a newer version was available and gave the command
> to update it. What are the consequences of using pip to upgrade repository
> installed modules?
>
> I ask because 16.04 is LTS and won't be getting version upgrades unless they
> are security related. Also pandas is in the repositories but the module
> pandas-datareader, which I may need to use, is not.
>
> Regards,  Jim
>
>
>>
>> On Sat, Jan 7, 2017 at 4:39 PM, Chris Angelico  wrote:
>>>
>>> On Sun, Jan 8, 2017 at 9:34 AM, Michael Torrie  wrote:

 On 01/07/2017 11:39 AM, Clint Moyer wrote:
>
> All Linux operating systems come with Python installed, with more
> recent systems such as Arch defaulting /usr/bin/python to Python3,
> since Python2 discontinued some 7-9 years ago.


 Poor choice of words, in my opinion.  Python 2 has not received new
 features for 7-9 years now but it certainly hasn't been "discontinued"
 and won't be for some years yet, though new programming (and distros)
 should be with Python 3 now.
>>>
>>>
>>> Also, /usr/bin/python shouldn't be Python 3.
>>>
>>> https://www.python.org/dev/peps/pep-0394/
>>>
>>> But various distros are moving towards "don't have Python 2 installed
>>> by default", which consequently means "no system scripts depend on
>>> Python 2".
>>>
>>> ChrisA
>
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Cameron Simpson

On 07Jan2017 19:45, jim  wrote:

On 01/07/2017 05:58 PM, Clint Moyer wrote:

So to minimize your issues with installing Python packages, take the
path of least resistance and install through your system repo. And use
Python2 or Python3 explicitly to avoid conflicts.


As I mentioned in another post, most of the more popular modules I had 
installed on my old system using pip are available in the repository 
and I will use the repository to install them on the new system. I now 
understand that using sudo is a bad idea.


Cool.

One question from the earlier post that did not get answered concerned 
upgrading a repository installed module with pip.


I would recommend not. As soon as you get there:

 - if the vendor updates it, use apt-get (I know this doesn't fit your 
   situation with Ubuntu 16.04 LTS)


 - if you want a more modern version, now is the time to use virtualenv

The thing about LTS is that the vendor guarentees its stability. If you upgrade 
the vendor installed package using /usr/bin/pip (or pip3) as root, you're 
replacing the vendor supplied module with a newer one, which may break vendor 
supplied packages which use that module expected the _old_ behaviour.


So endeavour to leave the vendor suppplied stuff entirely alone except for 
apt-get style updates.


Instead, make a virtualenv an upgrade it with a newer package.

To get started on the new system I installed pip3 from the repository. The 
first time I used it to install a module it said a newer version was available 
and gave the command to update it. What are the consequences of using pip to 
upgrade repository installed modules?


In theory, if the newer version of the module installs a breaking change it can 
break things in the system which might use that module and expect its old 
behaviour. Also, _sometimes_, vendors supply patches versions of packages, 
possibly including python modules. If they're modified/patched, there is 
probably a reason. You'd be undoing that patch.


I ask because 16.04 is LTS and won't be getting version upgrades 
unless they are security related. Also pandas is in the repositories but the 
module pandas-datareader, which I may need to use, is not.


Again: make a virtualenv as yourself.

Its pip can be run as yourself, therefore cannot accidentally modify system 
module. It's pip can freely upgrade a older module. If you install a module 
_not_ supplied by the vendor, the virtualenv pip can freely do that, and _also_ 
upgrade a required module should that be required (PyPI package definitions let 
a module specify required revisions of other modules it may use).


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Cameron Simpson

On 07Jan2017 19:02, jim  wrote:

On 01/07/2017 03:17 PM, Dennis Lee Bieber wrote:

On Sat, 7 Jan 2017 12:22:45 -0600, jim  declaimed
the following:

What is "system python"? If I do $ which python I get /usr/bin/python
which points to python 2.7xx. So if everything I added was for python 3
either using pip3 or apt-get would I be adding to "system python"?


What does
which python3
return?


jfb@jims-1604:~$ which python3
/usr/bin/python3


That is the system (Ubuntu supplied) python3. /usr/bin belongs to the vendor.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Pablo Lucena
How about using the second usage of builtin iter()?

In [92]: iter?
Docstring:
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator

Get an iterator from an object.  In the first form, the argument must
supply its own iterator, or be a sequence.
*In the second form, the callable is called until it returns the sentinel.
 <<<-this one <<<---*
Type:  builtin_function_or_method


In [88]: numbers
Out[88]: [1, 9, 8, 11, 22, 4, 0, 3, 5, 6]

# create iterator over the numbers to make callable simple
# you may pre-sort or do w/e as needed of course
In [89]: numbers_it = iter(numbers)

# callable passed into iter - you may customize this
# using functools.partial if need to add function arguments
In [90]: def grab_until():
...: return next(numbers_it)
...:

# here 0 is the 'sentinel' ('int()' would work as well as you have
# the iterator produced by iter() here stops as soon as sentinel value
# is encountered
In [91]: list(iter(grab_until, 0))
Out[91]: [1, 9, 8, 11, 22, 4]



Hope this helps

Pablo

On Sat, Jan 7, 2017 at 8:38 AM, Jussi Piitulainen <
jussi.piitulai...@helsinki.fi> wrote:

> Rustom Mody writes:
> > On a Saturday, Jussi Piitulainen wrote:
>
> [snip]
>
> >> You switched to a simpler operator. Would Haskell notice that
> >>
> >>def minabs(x, y): return min(x, y, key = abs)
> >>
> >> has a meaningful zero? Surely it has its limits somewhere and then
> >> the programmer needs to supply the information.
> >
> > Over ℕ multiply has 1 identity and 0 absorbent
> > min has ∞ as identity and 0 as absorbent
> > If you allow for ∞ they are quite the same
>
> There is nothing like ∞ in Python ints. Floats would have one, but we
> can leave empty minimum undefined instead. No worries.
>
> > Below I am pretending that 100 = ∞
>
> Quite silly but fortunately not really relevant.
>
> > Here are two lazy functions:
> > mul.0.y = 0  -- Lazy in y ie y not evaluated
> > mul.x.y = x*y
> >
> > minm.0.y = 0  -- likewise lazy in y
> > minm.x.y = min.x.y
>
> Now I don't see any reason to avoid the actual function that's been the
> example in this thread:
>
> minabs.0.y = 0
> minabs.x.y = x if abs.x <= abs.y else y
>
> And now I see where the desired behaviour comes from in Haskell. The
> absorbing clause is redundant, apart from providing the specific
> stopping condition explicitly.
>
> > Now at the interpreter:
> > ? foldr.minm . 100.[1,2,3,4]
> > 1 : Int
> > ? foldr.minm . 100.[1,2,3,4,0]
> > 0 : Int
> > ? foldr.minm . 100.([1,2,3,4,0]++[1...])
> > 0 : Int
> >
> > The last expression appended [1,2,3,4,0] to the infinite list of numbers.
> >
> > More succinctly:
> > ? foldr.minm . 100.([1,2,3,4,0]++undefined)
> > 0 : Int
> >
> > Both these are extremal examples of what Peter is asking for — avoiding
> an
> > expensive computation
>
> Ok. Thanks.
> --
> https://mail.python.org/mailman/listinfo/python-list
>



-- 
*Pablo Lucena*
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread jim

On 01/07/2017 05:58 PM, Clint Moyer wrote:

Not sure how you guys got this thread so far off topic, but I think it
is valuable to present the current situation in the context of Jim's
sudo question. Staying on topic, the emphasis should be on taking the
path of least resistance with your current OS. The only thing to be
gleaned from PEP394 is that users should not put faith or expectations
in what their /usr/bin/python symlink points to. Most systems point to
Python2, but it is not guaranteed.

So to minimize your issues with installing Python packages, take the
path of least resistance and install through your system repo. And use
Python2 or Python3 explicitly to avoid conflicts.

--
Clint



As I mentioned in another post, most of the more popular modules I had 
installed on my old system using pip are available in the repository and 
I will use the repository to install them on the new system. I now 
understand that using sudo is a bad idea.


One question from the earlier post that did not get answered concerned 
upgrading a repository installed module with pip. To get started on the 
new system I installed pip3 from the repository. The first time I used 
it to install a module it said a newer version was available and gave 
the command to update it. What are the consequences of using pip to 
upgrade repository installed modules?


I ask because 16.04 is LTS and won't be getting version upgrades unless 
they are security related. Also pandas is in the repositories but the 
module pandas-datareader, which I may need to use, is not.


Regards,  Jim



On Sat, Jan 7, 2017 at 4:39 PM, Chris Angelico  wrote:

On Sun, Jan 8, 2017 at 9:34 AM, Michael Torrie  wrote:

On 01/07/2017 11:39 AM, Clint Moyer wrote:

All Linux operating systems come with Python installed, with more
recent systems such as Arch defaulting /usr/bin/python to Python3,
since Python2 discontinued some 7-9 years ago.


Poor choice of words, in my opinion.  Python 2 has not received new
features for 7-9 years now but it certainly hasn't been "discontinued"
and won't be for some years yet, though new programming (and distros)
should be with Python 3 now.


Also, /usr/bin/python shouldn't be Python 3.

https://www.python.org/dev/peps/pep-0394/

But various distros are moving towards "don't have Python 2 installed
by default", which consequently means "no system scripts depend on
Python 2".

ChrisA



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


Re: Can't match str/unicode

2017-01-07 Thread Steve D'Aprano
On Sun, 8 Jan 2017 08:40 am, CM wrote:

> So what's going on here? Why isn't a string with the content 'match' equal
> to another string with the content 'match'?

You don't know that the content is 'match'. All you know is that when
printed, it *looks like* 'match'.

Hint:

s = 'match '
print 'match', s  # they look the same
print 'match' == s  # but they aren't the same


Start by printing repr(candidate_text) and see what you really have.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Using sudo with pip3?

2017-01-07 Thread jim

On 01/07/2017 03:17 PM, Dennis Lee Bieber wrote:

On Sat, 7 Jan 2017 12:22:45 -0600, jim  declaimed
the following:



What is "system python"? If I do $ which python I get /usr/bin/python
which points to python 2.7xx. So if everything I added was for python 3
either using pip3 or apt-get would I be adding to "system python"?



What does

which python3

return?


jfb@jims-1604:~$ which python3
/usr/bin/python3

Regards,  Jim


wulfraed@Jessie:~$ which python
/usr/bin/python
wulfraed@Jessie:~$ which python3
/usr/bin/python3
wulfraed@Jessie:~$ python
Python 2.7.9 (default, Mar  1 2015, 12:57:24)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.



wulfraed@Jessie:~$ python3
Python 3.4.2 (default, Oct  8 2014, 10:45:20)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.



wulfraed@Jessie:~$

I consider both of those to be "system" as I don't recall explicitly
asking for either (Debian running in VirtualBox)




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


Re: Using sudo with pip3?

2017-01-07 Thread Clint Moyer
Not sure how you guys got this thread so far off topic, but I think it
is valuable to present the current situation in the context of Jim's
sudo question. Staying on topic, the emphasis should be on taking the
path of least resistance with your current OS. The only thing to be
gleaned from PEP394 is that users should not put faith or expectations
in what their /usr/bin/python symlink points to. Most systems point to
Python2, but it is not guaranteed.

So to minimize your issues with installing Python packages, take the
path of least resistance and install through your system repo. And use
Python2 or Python3 explicitly to avoid conflicts.

--
Clint



On Sat, Jan 7, 2017 at 4:39 PM, Chris Angelico  wrote:
> On Sun, Jan 8, 2017 at 9:34 AM, Michael Torrie  wrote:
>> On 01/07/2017 11:39 AM, Clint Moyer wrote:
>>> All Linux operating systems come with Python installed, with more
>>> recent systems such as Arch defaulting /usr/bin/python to Python3,
>>> since Python2 discontinued some 7-9 years ago.
>>
>> Poor choice of words, in my opinion.  Python 2 has not received new
>> features for 7-9 years now but it certainly hasn't been "discontinued"
>> and won't be for some years yet, though new programming (and distros)
>> should be with Python 3 now.
>
> Also, /usr/bin/python shouldn't be Python 3.
>
> https://www.python.org/dev/peps/pep-0394/
>
> But various distros are moving towards "don't have Python 2 installed
> by default", which consequently means "no system scripts depend on
> Python 2".
>
> ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 3 dict: .keys(), .values(), and .item()

2017-01-07 Thread Steve D'Aprano
On Sun, 8 Jan 2017 08:48 am, Ethan Furman wrote:

> In Python 2 we have:
> 
>dict().keys()   \
>dict().items()   -->  separate list() of the results
>dict().values() /
> 
> and
> 
>dict().iter_keys()   \
>dict().iter_items()   -->  integrated iter() of the results
>dict().iter_values() /

You missed another group of methods:

viewkeys()
viewitems()
viewvalues()

which are integrated, iterable, set-like views of the keys/items/values.


> By "separate list" I mean a snapshot of the dict at the time, and by
> "integrated iter()" I mean  changes to the dict during iteration are
> seen by the iter.
> 
> In Python 3 the iter_* methods replaced the list() type methods, 

Its actually the view* methods.


> which 
> makes sense from the point-of-view of moving to a more iterator based
> language; however, as a result of that change the typical "iterate over
> a dict" operation now has a built-in gotcha: modifying the dict during
> the iteration can now cause exceptions.

Even in Python 2, modifying the dict during iteration can cause exceptions:

for key in adict:  # iterate over the dict directly
...


As usual, the standard rule applies: don't add or remove elements of a
collection while you are iterating over it.

This doesn't work either:

for i, x in enumerate(alist):
if condition(x):
del alist(i)


and has a similar solution:

for i, x in enumerate(list(alist)):
...

except that's more commonly written using slicing:

for i, x in enumerate(alist[:]):
...


For both dicts and lists, it is safe to modify existing elements:

adict[key] = new_value  # provided key already exists

alist[index] = new_value


are both safe, but insertions and deletions are not.


> The solution, of course, is simple: surround the iterator call with
> list():

There's nothing magical about list. You could use tuple, or (sometimes) set
or frozenset. But list is good.


>list(dict.keys())
>list(dict.items())
>list(dict.values())
> 
>for k, v in list(flag._value2member_map_.items()):
>...
> 
> The solution, however, feels a lot more boilerplate-ish.  Either the
> programmer takes a lot more care to remember the current state of the dict
> (since it's no longer a snapshot), or "list()" is sprinkled around every
> iterator access.

Not *every* view access. Only the ones where you insert/delete elements.


> In other words, what used to be a completely safe operation now is not.
> 
> Thoughts?

The old Python 2 keys/values/items methods used to make a copy of the
elements, whether you needed a copy or not. Now making a copy is your
responsibility. That feels more Pythonic to me.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Using sudo with pip3?

2017-01-07 Thread Cameron Simpson

On 08Jan2017 11:22, Chris Angelico  wrote:

On Sun, Jan 8, 2017 at 10:51 AM, Cameron Simpson  wrote:

Here's an example:

 $ mkdir ~/var ~/var/venv  # where I keep my virtualenvs
 $ virtualenv -p /usr/bin/python3 --system-site-packages ~/var/venv/3
 $ ~/var/venv/3/bin/python3# invokes the virtualenv python3
 $ ~/var/venv/3/bin/pip3   # invokes the virtualenv pip3
 $ ln -s ~/var/venv/3/bin/python3 ~/bin/.  # make these my default
 $ ln -s ~/var/venv/3/bin/pip3 ~/bin/.

From this point on "pip3" should execute your own $HOME/bin/pip3, which
comes from the virtualenv and installs in ~/var/venv/3/lib/...


Can you do the same with the standard library 'venv' module? I
generally recommend and prefer that over the third-party 'virtualenv',
which achieves what it does via a series of hacks.


Probably? Haven't tried. I thought the venv module was essentially virtualenv's 
innards presented as a module, but have never tested it.


Do I need to retire my "venv" shell script (convenience wrapper for the 
virtualenv command)?


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Error with math.sqrt

2017-01-07 Thread Chris Angelico
On Sun, Jan 8, 2017 at 11:15 AM, Jack Harvey  wrote:
> I'm starting out with Python 3.5.  My current frustration is with:
>
>
 math.sqrt(25)
> Traceback (most recent call last):
>   File "", line 1, in 
> math.sqrt(25)
> NameError: name 'math' is not defined

>
>
> Advice?

A lot of Python's features are in what's called the "standard library"
- a set of modules that you can call up with the 'import' statement.
In this case, all you need is to start with this line:

import math

Once you do that, everything in the math module (including math.sqrt)
should be available.

Enjoy!

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Chris Angelico
On Sun, Jan 8, 2017 at 10:51 AM, Cameron Simpson  wrote:
> Here's an example:
>
>  $ mkdir ~/var ~/var/venv  # where I keep my virtualenvs
>  $ virtualenv -p /usr/bin/python3 --system-site-packages ~/var/venv/3
>  $ ~/var/venv/3/bin/python3# invokes the virtualenv python3
>  $ ~/var/venv/3/bin/pip3   # invokes the virtualenv pip3
>  $ ln -s ~/var/venv/3/bin/python3 ~/bin/.  # make these my default
>  $ ln -s ~/var/venv/3/bin/pip3 ~/bin/.
>
> From this point on "pip3" should execute your own $HOME/bin/pip3, which
> comes from the virtualenv and installs in ~/var/venv/3/lib/...

Can you do the same with the standard library 'venv' module? I
generally recommend and prefer that over the third-party 'virtualenv',
which achieves what it does via a series of hacks.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Error with math.sqrt

2017-01-07 Thread Jack Harvey
I'm starting out with Python 3.5.  My current frustration is with:


>>> math.sqrt(25)
Traceback (most recent call last):
  File "", line 1, in 
math.sqrt(25)
NameError: name 'math' is not defined
>>>


Advice?


Jack
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Cameron Simpson

On 07Jan2017 12:22, jim  wrote:

On 01/06/2017 08:24 PM, Cameron Simpson wrote:

On 06Jan2017 23:03, Clint Moyer  wrote:

Packages supplied by your distribution can be trusted more than packages
from PyPi. Just my two cents.
Most distros offer nearly all the useful Python modules directly from the
repo.


I would agree with this on the whole. And also that it is generally
better to add modules to your system python via the distro's repo
because that bring benefit to every user on the system, not just yourself.


What is "system python"? If I do $ which python I get /usr/bin/python 
which points to python 2.7xx. So if everything I added was for python 
3 either using pip3 or apt-get would I be adding to "system python"?


Whatever python(s) came from the vendor. If they're in /bin or /usr/bin, then 
they will almost certainly be the vendor python.


The thing is, many distros will have an aim to move to python 3 as their python 
for tooling (python 2 is essentially maintenance only - see PEP 404), and there 
will be a mix of python 2 and python 3 programs on your system, both core 
vendor-made tools (eg yum on redhat/centos) or third party but vendor supplied 
stuff (== anything else that apt-get will give you).


Basicly, for Ubuntu the "system" python is anything supplied by apt-get and 
therefore _managed_ by apt. This is why you should avoid "become root and run 
pip3 install" on the whole - you may well tread in the space owned by the 
vendor because Ubuntu supply many python packages.


Normally a vendor will not install its packages in /opt or /usr/local or in 
/home/wherever; that leaves such spaces as safe for third party stuff installs.


So, instead, make a python3 virtualenv as yourself and use _its_ pip3 for 
installs; they will land in the virtualenv, away from the vendor files.


When you make a virtualenv you base it on an existing python; if you tell it to 
use /usr/bin/python3 that will be the underlying python executable, but the 
"python3" from inside the virutalenv will be configured to use the virtualenv's 
packages.


I generally configure my virtualenvs to leverag the system's packages, as this 
lets me benefit if more vendor supplied packages are added. (Some virtualenvs 
are not, in order to isolate them from changes.)


Here's an example:

 $ mkdir ~/var ~/var/venv  # where I keep my virtualenvs
 $ virtualenv -p /usr/bin/python3 --system-site-packages ~/var/venv/3
 $ ~/var/venv/3/bin/python3# invokes the virtualenv python3
 $ ~/var/venv/3/bin/pip3   # invokes the virtualenv pip3
 $ ln -s ~/var/venv/3/bin/python3 ~/bin/.  # make these my default
 $ ln -s ~/var/venv/3/bin/pip3 ~/bin/.

From this point on "pip3" should execute your own $HOME/bin/pip3, which comes 

from the virtualenv and installs in ~/var/venv/3/lib/...

In this way:

 - you get whatever vendor supplied packages there are, including any updates


 - you can install freely with pip3 safe in the knowledge that it will be in 
   ~/var/venv/3, away from the system packages; pip3 install packages will 
   override any vendor supplied one for the venv python3


A number of years ago I had virtualenv installed.  At the time I remember it 
took me a while to get it installed and working.


It is almost a one liner these days, see example above.

Right now I am working on some scripts to download some financial date using 
Selenium and paste it into Libreoffice Calc spreadsheets.  Will using 
virtualenv have any effect on me running those scripts?


I wouldn't think so. Especially if they already work.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Can't match str/unicode

2017-01-07 Thread Chris Angelico
On Sun, Jan 8, 2017 at 8:40 AM, CM  wrote:
>
> This is candidate_text: match
> 
> 
> False
>
> and, of course, doesn't enter that "do something" loop since apparently 
> candidate_text != 'match'...even though it seems like it does.
>
> So what's going on here? Why isn't a string with the content 'match' equal to 
> another string with the content 'match'?

What happens if you print the repr of each string? Or, if one of them
truly is a literal, just print the repr of the one you got from
win32com.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Chris Angelico
On Sun, Jan 8, 2017 at 9:34 AM, Michael Torrie  wrote:
> On 01/07/2017 11:39 AM, Clint Moyer wrote:
>> All Linux operating systems come with Python installed, with more
>> recent systems such as Arch defaulting /usr/bin/python to Python3,
>> since Python2 discontinued some 7-9 years ago.
>
> Poor choice of words, in my opinion.  Python 2 has not received new
> features for 7-9 years now but it certainly hasn't been "discontinued"
> and won't be for some years yet, though new programming (and distros)
> should be with Python 3 now.

Also, /usr/bin/python shouldn't be Python 3.

https://www.python.org/dev/peps/pep-0394/

But various distros are moving towards "don't have Python 2 installed
by default", which consequently means "no system scripts depend on
Python 2".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 3 dict: .keys(), .values(), and .item()

2017-01-07 Thread Ethan Furman

On 01/07/2017 03:04 PM, Peter Otten wrote:

Ethan Furman wrote:


In Python 2 we have:

dict().keys()   \
dict().items()   -->  separate list() of the results
dict().values() /

and

dict().iter_keys()   \
dict().iter_items()   -->  integrated iter() of the results
dict().iter_values() /


I guess you didn't use these as often as I did ;)

By the way, there are also the virtually unused/unknown dict.viewXXX()
methods that are the exact? equivalent to the dict.XXX() methods in Python
3.


Ah, right -- in fact, those are the ones that got transplanted, I think.


In other words, what used to be a completely safe operation now is not.

Thoughts?


Is code that was written for Python 3 riddled with list(...) calls?


Generally, or just around dicts?  I know I've placed list() around a few dict
calls (when I am going to modify the dict in the loop) or I make a separate list
to save the modifications and the bulk change in a separate loop.


Do you see

RuntimeError: dictionary changed size during iteration

regularly?


No, thank goodness.  Still embarrassing when it happens, though.  :(

Thinking on it some more, I'm pretty sure I would have ended up with another
exception of a different flavor, so overall no extra harm done.  ;)

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: python 3 dict: .keys(), .values(), and .item()

2017-01-07 Thread Peter Otten
Ethan Furman wrote:

> In Python 2 we have:
> 
>dict().keys()   \
>dict().items()   -->  separate list() of the results
>dict().values() /
> 
> and
> 
>dict().iter_keys()   \
>dict().iter_items()   -->  integrated iter() of the results
>dict().iter_values() /

I guess you didn't use these as often as I did ;)

By the way, there are also the virtually unused/unknown dict.viewXXX() 
methods that are the exact? equivalent to the dict.XXX() methods in Python 
3.

> By "separate list" I mean a snapshot of the dict at the time, and by
> "integrated iter()" I mean  changes to the dict during iteration are
> seen by the iter.
> 
> In Python 3 the iter_* methods replaced the list() type methods, which
> makes sense from the point-of-view of moving to a more iterator based
> language; however, as a result of that change the typical "iterate over
> a dict" operation now has a built-in gotcha: modifying the dict during
> the iteration can now cause exceptions.
> 
> The solution, of course, is simple: surround the iterator call with
> list():
> 
>list(dict.keys())
>list(dict.items())
>list(dict.values())
> 
>for k, v in list(flag._value2member_map_.items()):
>...
> 
> The solution, however, feels a lot more boilerplate-ish.  Either the
> programmer takes a lot more care to remember the current state of the dict
> (since it's no longer a snapshot), or "list()" is sprinkled around every
> iterator access.
> 
> In other words, what used to be a completely safe operation now is not.
> 
> Thoughts?

Is code that was written for Python 3 riddled with list(...) calls?

That's not my impression.

Do you see

RuntimeError: dictionary changed size during iteration

regularly? 

I don't, and while I wouldn't have changed the dict interface I think Python 
3's items() and values() -- who uses keys()? -- are clearly the better 
defaults.

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


Re: Using sudo with pip3?

2017-01-07 Thread Michael Torrie
On 01/07/2017 11:39 AM, Clint Moyer wrote:
> All Linux operating systems come with Python installed, with more
> recent systems such as Arch defaulting /usr/bin/python to Python3,
> since Python2 discontinued some 7-9 years ago. 

Poor choice of words, in my opinion.  Python 2 has not received new
features for 7-9 years now but it certainly hasn't been "discontinued"
and won't be for some years yet, though new programming (and distros)
should be with Python 3 now.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread Clint Moyer
All Linux operating systems come with Python installed, with more
recent systems such as Arch defaulting /usr/bin/python to Python3,
since Python2 discontinued some 7-9 years ago. I believe Ubuntu still
defaults that to Python2, however.

So when you run pip3 you are attempting to download and install a
package from the internet, specifically the PyPi repository. You are
deliberately avoiding your Package Repository from your OS in this
scenario. That's fine, but when the package requires root privilege to
install arbitrary executables and bindings in the root filesystem, you
are taking on too much risk to be acceptable.

Which is why nearly all current Linux OS systems have these common
Python packages ready for instant download, through the respective
repo.

I find the benefit of adding libraries directly to your system's
Python, outweighs the extra effort of setting up a VirtualEnv. When it
comes to individual projects, that's when I'll set up the env. Being
able to run those commands directly:

$ ansible-playbook run.yml

Is quite useful. Working in the field, sadly the most common
roadblocks I see are difficulties installing through Pip, or even a
VirtualEnv. Much better off going through your system, and learning
what other dependencies may be needed.
--
Clint


On Sat, Jan 7, 2017 at 11:22 AM, jim  wrote:
> On 01/06/2017 08:24 PM, Cameron Simpson wrote:
>>
>> On 06Jan2017 23:03, Clint Moyer  wrote:
>
>
> Thanks everyone for the advice. Please note in my following comments I am
> not arguing with anyone, merely trying to understand. I am not a
> professional programmer, just someone who enjoys programing for my own
> use/enjoyment and I am the only user of this system.
>
>>> Packages supplied by your distribution can be trusted more than packages
>>> from PyPi. Just my two cents.
>>> Most distros offer nearly all the useful Python modules directly from the
>>> repo.
>>
>>
>> I would agree with this on the whole. And also that it is generally
>> better to add modules to your system python via the distro's repo
>> because that bring benefit to every user on the system, not just yourself.
>
>
> What is "system python"? If I do $ which python I get /usr/bin/python which
> points to python 2.7xx. So if everything I added was for python 3 either
> using pip3 or apt-get would I be adding to "system python"?
>
> I see that most of the "major" python3 modules I had installed, with the
> exception of scripy, are in the repository. If I upgraded one of the
> repository modules using pip3 would I lose the benefits of installing from
> the repository? I know it seems to be possible as I installed pip3 from the
> repository.  The first time I used it to install a module it informed me
> there was a more current version available and showed me the command to
> update. I updated and it seems to be fine.
>
>>> Virtual environments are great, but if you want to add libraries to your
>>> system interpreter I'd recommend a simple sync through your repo.
>>
>>
>> I'm directly advocating _not_ adding PyPI packages to the system
>> interpreter.  If nothing else, they may differ in behaviour and
>> potentially actually break system behaviour.
>>
>> Having your on virtualenv is good for: adding packages no provided by
>> your vendor, adding packages deliberately different from those from your
>> vendor (eg newer versions with specific bugfixes or extra features),
>> having an isolated environment for packages (you can make more than one
>> virtual environment).
>>
>> And of course it avoids interfering with your system python install.
>
>
> A number of years ago I had virtualenv installed.  At the time I remember it
> took me a while to get it installed and working. Right now I am working on
> some scripts to download some financial date using Selenium and paste it
> into Libreoffice Calc spreadsheets.  Will using virtualenv have any effect
> on me running those scripts?
>
> Thanks,  Jim
>
>
>>
>> Cheers,
>> Cameron Simpson 
>
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


python 3 dict: .keys(), .values(), and .item()

2017-01-07 Thread Ethan Furman

In Python 2 we have:

  dict().keys()   \
  dict().items()   -->  separate list() of the results
  dict().values() /

and

  dict().iter_keys()   \
  dict().iter_items()   -->  integrated iter() of the results
  dict().iter_values() /

By "separate list" I mean a snapshot of the dict at the time, and by
"integrated iter()" I mean  changes to the dict during iteration are
seen by the iter.

In Python 3 the iter_* methods replaced the list() type methods, which
makes sense from the point-of-view of moving to a more iterator based
language; however, as a result of that change the typical "iterate over
a dict" operation now has a built-in gotcha: modifying the dict during
the iteration can now cause exceptions.

The solution, of course, is simple: surround the iterator call with list():

  list(dict.keys())
  list(dict.items())
  list(dict.values())

  for k, v in list(flag._value2member_map_.items()):
  ...

The solution, however, feels a lot more boilerplate-ish.  Either the
programmer takes a lot more care to remember the current state of the dict
(since it's no longer a snapshot), or "list()" is sprinkled around every
iterator access.

In other words, what used to be a completely safe operation now is not.

Thoughts?

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Can't match str/unicode

2017-01-07 Thread CM
This is probably very simple but I get confused when it comes to encoding and 
am generally rusty. (What follows is in Python 2.7; I know.).

I'm scraping a Word docx using win32com and am just trying to do some matching 
rules to find certain paragraphs that, for testing purposes, equal the word 
'match', which I know exists as its own "paragraph" in the target document. 
First, this is at the top of the file:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

Then this is the relevant code:

candidate_text = Paragraph.Range.Text.encode('utf-8')
print 'This is candidate_text:', candidate_text
print type(candidate_text)   
print type('match')
print candidate_text == 'match'
if candidate_text == 'match':
 #  do something...

And that section produces this:

This is candidate_text: match


False

and, of course, doesn't enter that "do something" loop since apparently 
candidate_text != 'match'...even though it seems like it does.

So what's going on here? Why isn't a string with the content 'match' equal to 
another string with the content 'match'?

I've also tried it with removing that .encode part and the encoding part at the 
very top, but then the candidate_text is a unicode object that I also can't get 
to match to anything.

What am I doing wrong? How should I approach this? Thanks.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The hardest problem in computer science...

2017-01-07 Thread Ethan Furman

On 01/06/2017 11:34 PM, Steve D'Aprano wrote:

On Sat, 7 Jan 2017 12:03 am, Steve D'Aprano wrote:


The second hardest problem in computer science is cache invalidation.

The *hardest* problem is naming things.


After puzzling over this for three days, it suddenly hit me:

Theme = namedtuple("Theme", "vline tee corner")

DEFAULT = Theme("│  ", "├─ ", "└─ ")
BOLD = Theme("┃  ", "┣━ ", "┗━ ")
ASCII = Theme("|  ", "|- ", "+- ")

def draw_tree(tree, theme=DEFAULT):
 ...


Ya know, that looks an /awful/ lot like a collection!  Maybe even an Enum?  ;)

-- 8< ---
from aenum import Enum   # note the 'a' before the 'enum'  :)

class Theme(Enum, init='v vr llc'):
DEFAULT = "│  ", "├─ ", "└─ "
BOLD = "┃  ", "┣━ ", "┗━ "
ASCII = "|  ", "|- ", "+- "

def draw_tree(tree, theme=Theme.DEFAULT):
print(theme.v)
print(theme.vr)
print(theme.v)
print(theme.llc)

draw_tree(None)
-- 8< ---

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: Using sudo with pip3?

2017-01-07 Thread jim

On 01/06/2017 08:24 PM, Cameron Simpson wrote:

On 06Jan2017 23:03, Clint Moyer  wrote:


Thanks everyone for the advice. Please note in my following comments I 
am not arguing with anyone, merely trying to understand. I am not a 
professional programmer, just someone who enjoys programing for my own 
use/enjoyment and I am the only user of this system.



Packages supplied by your distribution can be trusted more than packages
from PyPi. Just my two cents.
Most distros offer nearly all the useful Python modules directly from the
repo.


I would agree with this on the whole. And also that it is generally
better to add modules to your system python via the distro's repo
because that bring benefit to every user on the system, not just yourself.


What is "system python"? If I do $ which python I get /usr/bin/python 
which points to python 2.7xx. So if everything I added was for python 3 
either using pip3 or apt-get would I be adding to "system python"?


I see that most of the "major" python3 modules I had installed, with the 
exception of scripy, are in the repository. If I upgraded one of the 
repository modules using pip3 would I lose the benefits of installing 
from the repository? I know it seems to be possible as I installed pip3 
from the repository.  The first time I used it to install a module it 
informed me there was a more current version available and showed me the 
command to update. I updated and it seems to be fine.



Virtual environments are great, but if you want to add libraries to your
system interpreter I'd recommend a simple sync through your repo.


I'm directly advocating _not_ adding PyPI packages to the system
interpreter.  If nothing else, they may differ in behaviour and
potentially actually break system behaviour.

Having your on virtualenv is good for: adding packages no provided by
your vendor, adding packages deliberately different from those from your
vendor (eg newer versions with specific bugfixes or extra features),
having an isolated environment for packages (you can make more than one
virtual environment).

And of course it avoids interfering with your system python install.


A number of years ago I had virtualenv installed.  At the time I 
remember it took me a while to get it installed and working. Right now I 
am working on some scripts to download some financial date using 
Selenium and paste it into Libreoffice Calc spreadsheets.  Will using 
virtualenv have any effect on me running those scripts?


Thanks,  Jim



Cheers,
Cameron Simpson 



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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Jussi Piitulainen
Rustom Mody writes:
> On a Saturday, Jussi Piitulainen wrote:

[snip]

>> You switched to a simpler operator. Would Haskell notice that
>> 
>>def minabs(x, y): return min(x, y, key = abs)
>> 
>> has a meaningful zero? Surely it has its limits somewhere and then
>> the programmer needs to supply the information.
>
> Over ℕ multiply has 1 identity and 0 absorbent
> min has ∞ as identity and 0 as absorbent
> If you allow for ∞ they are quite the same

There is nothing like ∞ in Python ints. Floats would have one, but we
can leave empty minimum undefined instead. No worries.

> Below I am pretending that 100 = ∞

Quite silly but fortunately not really relevant.

> Here are two lazy functions:
> mul.0.y = 0  -- Lazy in y ie y not evaluated
> mul.x.y = x*y
>
> minm.0.y = 0  -- likewise lazy in y
> minm.x.y = min.x.y

Now I don't see any reason to avoid the actual function that's been the
example in this thread:

minabs.0.y = 0
minabs.x.y = x if abs.x <= abs.y else y 

And now I see where the desired behaviour comes from in Haskell. The
absorbing clause is redundant, apart from providing the specific
stopping condition explicitly.

> Now at the interpreter:
> ? foldr.minm . 100.[1,2,3,4]
> 1 : Int
> ? foldr.minm . 100.[1,2,3,4,0]
> 0 : Int
> ? foldr.minm . 100.([1,2,3,4,0]++[1...])
> 0 : Int
>
> The last expression appended [1,2,3,4,0] to the infinite list of numbers.
>
> More succinctly:
> ? foldr.minm . 100.([1,2,3,4,0]++undefined)
> 0 : Int
>
> Both these are extremal examples of what Peter is asking for — avoiding an 
> expensive computation

Ok. Thanks.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pexpect

2017-01-07 Thread alister
On Fri, 06 Jan 2017 12:00:32 +1200, Iranna Mathapati wrote:

> Hi Team,
> 
> How to match latter(caps and small) ,numbers and # symbol in python
> pexpect.
> 
> 
> Thanks,
> Iranna M

Simple
just write a small program
 



-- 
New screensaver released: Curtains for Windows.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Rustom Mody
On Saturday, January 7, 2017 at 1:42:47 PM UTC+5:30, Jussi Piitulainen wrote:
> Rustom Mody writes:
> 
> > On Saturday, Jussi Piitulainen wrote:
> >> Paul Rubin writes:
> >> 
> >> > Peter Otten writes:
> >> >> How would you implement stopmin()?
> >> >
> >> > Use itertools.takewhile
> >> 
> >> How? It consumes the crucial stop element:
> >> 
> >>it = iter('what?')
> >>list(takewhile(str.isalpha, it)) # ==> ['w', 'h', 'a', 't']
> >>next(it, 42) # ==> 42
> >
> > I was also wondering how…
> > In a lazy language (eg haskell) with non-strict foldr (reduce but
> > rightwards) supplied non-strict operator this is trivial.
> > ie in python idiom with reduce being right_reduce
> > reduce(operator.mul, [1,2,0,4,...], 1)
> > the reduction would stop at the 0
> > Not sure how to simulate this in a strict language like python
> > Making fold(r) non-strict by using generators is ok
> > How to pass a non-strict operator?
> 
> I think it would have to be some really awkward pseudo-operator that
> throws an exception when it encounters its zero, and then reduce (or
> something outside reduce) would catch that exception. Something like
> that could be done but it would still be awkward. Don't wanna :)
> 
> You switched to a simpler operator. Would Haskell notice that
> 
>def minabs(x, y): return min(x, y, key = abs)
> 
> has a meaningful zero? Surely it has its limits somewhere and then the
> programmer needs to supply the information.



Over ℕ multiply has 1 identity and 0 absorbent
min has ∞ as identity and 0 as absorbent
If you allow for ∞ they are quite the same

Below I am pretending that 100 = ∞

Here are two lazy functions:
mul.0.y = 0  -- Lazy in y ie y not evaluated
mul.x.y = x*y

minm.0.y = 0  -- likewise lazy in y
minm.x.y = min.x.y

Now at the interpreter:
? foldr.minm . 100.[1,2,3,4]
1 : Int
? foldr.minm . 100.[1,2,3,4,0]
0 : Int
? foldr.minm . 100.([1,2,3,4,0]++[1...])
0 : Int

The last expression appended [1,2,3,4,0] to the infinite list of numbers.

More succinctly:
? foldr.minm . 100.([1,2,3,4,0]++undefined)
0 : Int

Both these are extremal examples of what Peter is asking for — avoiding an 
expensive computation
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Peter Otten
Peter Otten wrote:

> Example: you are looking for the minimum absolute value in a series of
> integers. As soon as you encounter the first 0 it's unnecessary extra work
> to check the remaining values, but the builtin min() will continue.
> 
> The solution is a minimum function that allows the user to specify a stop
> value:

Thanks everyone who contributed to this thread!

For those interested here's my collection of stopmin() implementations so 
far. Remember, there should be one ... *obvious* way to do it (emphasis 
mine).

$ cat stopmin_simple.py   
import functools
import operator
import re

from itertools import groupby
from functools import lru_cache


def steal_doc(f):
def set_doc(g):
sub = re.compile(r"\b{}\b".format(f.__name__)).sub
g.__doc__ = sub(g.__name__, f.__doc__)
return g
return set_doc


class Stop(Exception):
pass


def stopmin(items, *, key, stop):
"""
>>> def g():
... for i in reversed(range(10)):
... print(10*i)
... yield str(i)
>>> stopmin(g(), key=int, stop=5)
90
80
70
60
50
'5'
>>> stopmin(g(), key=int, stop=8.5)
90
80
'8'
>>> stopmin(g(), key=int, stop=9)
90
'9'
>>> stopmin([10, 9, -11, 7, -12], key=abs, stop=0)
7
>>> try: stopmin([], key=abs, stop=0)
... except ValueError: print('OK')
OK
>>> stopmin("a", key=lambda x: print(x) or "c", stop="b")
a
'a'
"""
def key2(value):
result = key(value)
if result <= stop:
raise Stop(value)
return result
try:
return min(items, key=key2)
except Stop as stop:
return stop.args[0]


def takeuntil(data, pred):
'''Take values from data until and including the first that
satisfies pred (until data is exhausted if none does).'''
for kind, group in groupby(data, pred):
if kind:
yield next(group)
break
else:
yield from group


@steal_doc(stopmin)
def stopmin_jussi(data, *, key, stop):
key = lru_cache(maxsize=1)(key)
return min(
takeuntil(data, lambda o: key(o) <= stop),
key=key
)


@steal_doc(stopmin)
def stopmin_wolfgang(iterable, *, key, stop):
key = lru_cache(maxsize=1)(key)

def take_until():
for e in iterable:
yield e
if key(e) <= stop:
break
return min(take_until(), key=key)


firstitem = operator.itemgetter(0)


@steal_doc(stopmin)
def stopmin_du(items, *, key, stop):
# decorate, process, undecorate
pairs = ((key(item), item) for item in items)
pairs = takeuntil(pairs, lambda pair: pair[0] <= stop)
return min(pairs, key=firstitem)[1]


@functools.total_ordering
class Pair:
__slots__ = ["key", "value"]

def __init__(self, key, value):
self.key = key
self.value = value

def __lt__(self, other):
return self.key < other.key


@steal_doc(stopmin)
def stopmin_du2(items, *, key, stop):
pairs = (Pair(key(item), item) for item in items)
pairs = takeuntil(pairs, lambda p: p.key <= stop)
return min(pairs).value


@steal_doc(stopmin)
def stopmin_steve(iterable, *, key, stop):
it = iter(iterable)
try:
smallest = next(it)
except StopIteration:
raise ValueError('empty iterable has no minimum')
keyed_smallest = key(smallest)
if keyed_smallest <= stop:
return smallest
for x in it:
y = key(x)
if y < keyed_smallest:
keyed_smallest = y
smallest = x
if y <= stop:
break
return smallest


@steal_doc(stopmin)
def stopmin2(items, key, stop):
pairs = ((key(item), item) for item in items)
try:
minkey, minval = next(pairs)
except StopIteration:
raise ValueError("stopmin2() arg is an empty sequence")
if minkey <= stop:
return minval
for k, v in pairs:
if k < minkey:
if k <= stop:
return v
minkey = k
minval = v
return minval
$ pep8 stopmin_simple.py
$ python3 -m doctest stopmin_simple.py


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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Peter Otten
Steve D'Aprano wrote:

> On Sat, 7 Jan 2017 01:04 am, Peter Otten wrote:
> 
>> Example: you are looking for the minimum absolute value in a series of
>> integers. As soon as you encounter the first 0 it's unnecessary extra
>> work to check the remaining values, but the builtin min() will continue.
>> 
>> The solution is a minimum function that allows the user to specify a stop
>> value:
>> 
> from itertools import count, chain
> stopmin(chain(reversed(range(10)), count()), key=abs, stop=0)
>> 0
>> 
>> How would you implement stopmin()?
> 
> That depends on whether you want to stop when you find a value *equal* to
> the stop value, or *less than* the stop value, or both.
> 
> It depends on whether you want to check for equality or check for any
> arbitrary condition.
> 
> It depends on whether you want the stop value to be included or not. (It
> looks like you do want it included.)
> 
> But I'd start with this:
> 
> 
> # not tested
> def stopmin(iterable, key=None, stop=None):
> it = iter(iterable)
> try:
> smallest = next(it)
> except StopIteration:
> raise ValueError('empty iterable has no minimum')
> else:
> if key is not None:
> keyed_smallest = key(smallest)

Must test for stop here.

> if key is None:
> for x in iterable:

Replace `iterable` with `it` in the for loops.

> if x < smallest:
> smallest = x
> if x == stop:
> break
> else:
> for x in iterable:
> y = key(x)
> if y < keyed_smallest:
> keyed_smallest = y
> smallest = x
> if y == stop:
> break
> return smallest

The whole distraction started when I wanted to avoid the straight-forward 
thing ;) 

As it turns out there is not as much legwork as I expected, particularly as 
I'm not interested in the no-key branch.
 
> Another possibility is to create a variant of itertools takewhile:
> 
> def takeuntil(predicate, iterable):
> # takeuntil(lambda x: x<5, [1,4,6,4,1]) --> 1 4 6
> for x in iterable:
> yield x
> if predicate(x):
> break
> 
> min(takeuntil(lambda x: x == 0, iterable), key=abs)
> 
> 
> py> from itertools import count, chain
> py> iterable = chain(reversed(range(10)), count())
> py> min(takeuntil(lambda x: x == 0, iterable), key=abs)
> 0
> py> iterable = chain(range(-9, 10), count())
> py> min(takeuntil(lambda x: x == 0, iterable), key=abs)
> 0


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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Peter Otten
Paul Rubin wrote:

> Peter Otten <__pete...@web.de> writes:
>> How would you implement stopmin()?
> 
> Use itertools.takewhile

I should have mentioned that I had already run into that -- let's call it -- 
off-by-one bug.

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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Peter Otten
Wolfgang Maier wrote:

> On 1/6/2017 15:04, Peter Otten wrote:
>> Example: you are looking for the minimum absolute value in a series of
>> integers. As soon as you encounter the first 0 it's unnecessary extra
>> work to check the remaining values, but the builtin min() will continue.
>>
>> The solution is a minimum function that allows the user to specify a stop
>> value:
>>
> from itertools import count, chain
> stopmin(chain(reversed(range(10)), count()), key=abs, stop=0)
>> 0
>>
>> How would you implement stopmin()?
>>
> 
> How about:
> 
> def stopmin (iterable, key, stop):
>  def take_until ():
>  for e in iterable:
>  yield e
>  if key(e) <= stop:
>  break
>  return min(take_until(), key=key)
> 
> ?

Clean and simple -- if it could be tweaked to invoke key() just once per 
item it would be perfect.

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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Peter Otten
Jussi Piitulainen wrote:

> Peter Otten writes:
> 
>> Example: you are looking for the minimum absolute value in a series of
>> integers. As soon as you encounter the first 0 it's unnecessary extra
>> work to check the remaining values, but the builtin min() will continue.
>>
>> The solution is a minimum function that allows the user to specify a stop
>> value:
>>
> from itertools import count, chain
> stopmin(chain(reversed(range(10)), count()), key=abs, stop=0)
>> 0
>>
>> How would you implement stopmin()?
> 
> Only let min see the data up to, but including, the stop value:

I should have mentioned that my actual use case has a costly key() function.

> from itertools import groupby
> 
> def takeuntil(data, pred):
> '''Take values from data until and including the first that
> satisfies pred (until data is exhausted if none does).'''
> for kind, group in groupby(data, pred):
> if kind:
> yield next(group)
> break
> else:
> yield from group

A clever takeuntil() implementation ;) I may steal it for my current 
favourite

def stopmin_du(items, *, key, stop):
# decorate, process, undecorate
pairs = ((key(item), item) for item in items)
pairs = takeuntil(pairs, lambda pair: pair[0] <= stop)
return min(pairs, key=firstitem)[1]


> def stopmin(data, key, stop):
> return min(takeuntil(data, lambda o : key(o) == stop),
>key = key)
> 
> data = '31415926'
> for stop in range(5):
> print(stop,
>   '=>', repr(''.join(takeuntil(data, lambda o : int(o) == stop))),
>   '=>', repr(stopmin(data, int, stop)))
> 
> # 0 => '31415926' => '1'
> # 1 => '31' => '1'
> # 2 => '3141592' => '1'
> # 3 => '3' => '3'
> # 4 => '314' => '1'
> 
> from itertools import count, chain
> print(stopmin(chain(reversed(range(10)), count()), key=abs, stop=0))
> print(stopmin(chain(reversed(range(10)), count()), key=abs, stop=3))
> 
> # 0
> # 3


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


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Steve D'Aprano
On Sat, 7 Jan 2017 07:06 am, Wolfgang Maier wrote:

> On 1/6/2017 15:04, Peter Otten wrote:
[...]
>> How would you implement stopmin()?
>>
> 
> How about:
> 
> def stopmin (iterable, key, stop):
>  def take_until ():
>  for e in iterable:
>  yield e
>  if key(e) <= stop:
>  break
>  return min(take_until(), key=key)

Heh, great minds think alike :-)




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


RE: Namedtuples: TypeError: 'str' object is not callable

2017-01-07 Thread Deborah Swanson
Gregory Ewing wrote, on January 07, 2017 1:13 AM
> 
> Deborah Swanson wrote:
> >   File "E:/Coding projects/Pycharm/Moving/moving_numberedtuples.py",
> > line 139, in moving()
> > for lst in map(listings._make, csv.reader(open('E:\\Coding 
> > projects\\Pycharm\\Moving\\Moving 2017 in.csv',"r"))):
> > TypeError: 'str' object is not callable
> 
> I know you've found the answer to this one, but as a general 
> tip, if you're getting an exception from a complicated line 
> like that, it can pay to break it down into simpler steps, 
> then you can see more clearly at what stage of the process 
> the exception is occurring. E.g.
> 
>file = open('E:\\Coding projects\\Pycharm\\Moving\\Moving 
> 2017 in.csv',"r")
>reader = csv.reader(file)
>rows = map(listings._make, reader)
>for lst in rows:
>  ...
> 
> In this case the traceback would have pointed you to the 
> third line, telling you that it was something to do with the 
> map() call.
> 
> -- 
> Greg

Thanks Greg. I'm really kicking myself for seeing everything in that
statement except the 'map('! Not really sure why it was invisible to me,
but the mind is very devious (also a Terrible Thing to Taste, according
to Ministry).

But your method gives a systematic way to break things down and look at
them one by one. It can be really dismaying to have a complex statement
like this one, that you copied from an example, and have it spit out
error after error no matter what you try.  Having a systematic method of
approach is quite probably guaranteed to succeed.

(I'll bet you can guess why I'm taking on numberedtuples. Hope to have
the rewritten code using them soon, and the more I look at it the surer
I am that numberedtuples will clean up a lot of fuzziness and wobbly
code. Thanks for the suggestion.) 

Deborah

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


Re: Using sudo with pip3?

2017-01-07 Thread Michiel Overtoom

> On 2017-01-07, at 03:24, Cameron Simpson  wrote:
> 
> Having your on virtualenv is good for: [...] having an isolated environment 
> for packages (you can make more than one virtual environment).

Yes, indeed. For example, if you have to maintain two different codebases, one 
using Django 1.8 and the other Django 1.10 and a slew of other packages, for 
example an older and newer version of allauth, you'd have to create two virtual 
environments or otherwise you'll end up with a broken situation.

Greetings,
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Namedtuples: TypeError: 'str' object is not callable

2017-01-07 Thread Gregory Ewing

Deborah Swanson wrote:

  File "E:/Coding projects/Pycharm/Moving/moving_numberedtuples.py",
line 139, in moving()
for lst in map(listings._make, csv.reader(open('E:\\Coding
projects\\Pycharm\\Moving\\Moving 2017 in.csv',"r"))):
TypeError: 'str' object is not callable


I know you've found the answer to this one, but as a general
tip, if you're getting an exception from a complicated line like
that, it can pay to break it down into simpler steps, then you
can see more clearly at what stage of the process the exception
is occurring. E.g.

  file = open('E:\\Coding projects\\Pycharm\\Moving\\Moving 2017 in.csv',"r")
  reader = csv.reader(file)
  rows = map(listings._make, reader)
  for lst in rows:
...

In this case the traceback would have pointed you to the third
line, telling you that it was something to do with the map()
call.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Jussi Piitulainen
Chris Angelico writes:

> On Sat, Jan 7, 2017 at 7:12 PM, Jussi Piitulainen wrote:

>> You switched to a simpler operator. Would Haskell notice that
>>
>>def minabs(x, y): return min(x, y, key = abs)
>>
>> has a meaningful zero? Surely it has its limits somewhere and then
>> the programmer needs to supply the information.
>
> If the return value of abs is int(0..) then yeah, it could. (Or
> whatever the notation is. That's Pike's limited-range-int type
> syntax.)

Maybe so. If Haskell abs has such types. (For integers, rationals,
whatever numeric types Haskell has, which I've quite forgotten, or it
may have even changed since I knew some Haskell. It's been a while.)

I rewrite the question so that the answer cannot be deduced from just
the types of the functions:

def minabs(x, y): return min(x, y, key = lambda w: max(w, -w))

Surely max of two ints is an int. Maybe the Haskell compiler could
specialize the type, but my question is, is it _guaranteed_ to do so,
and how should the programmer know to rely on that?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Chris Angelico
On Sat, Jan 7, 2017 at 7:12 PM, Jussi Piitulainen
 wrote:
> You switched to a simpler operator. Would Haskell notice that
>
>def minabs(x, y): return min(x, y, key = abs)
>
> has a meaningful zero? Surely it has its limits somewhere and then the
> programmer needs to supply the information.

If the return value of abs is int(0..) then yeah, it could. (Or
whatever the notation is. That's Pike's limited-range-int type
syntax.)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Jussi Piitulainen
Rustom Mody writes:

> On Saturday, Jussi Piitulainen wrote:
>> Paul Rubin writes:
>> 
>> > Peter Otten writes:
>> >> How would you implement stopmin()?
>> >
>> > Use itertools.takewhile
>> 
>> How? It consumes the crucial stop element:
>> 
>>it = iter('what?')
>>list(takewhile(str.isalpha, it)) # ==> ['w', 'h', 'a', 't']
>>next(it, 42) # ==> 42
>
> I was also wondering how…
> In a lazy language (eg haskell) with non-strict foldr (reduce but
> rightwards) supplied non-strict operator this is trivial.
> ie in python idiom with reduce being right_reduce
> reduce(operator.mul, [1,2,0,4,...], 1)
> the reduction would stop at the 0
> Not sure how to simulate this in a strict language like python
> Making fold(r) non-strict by using generators is ok
> How to pass a non-strict operator?

I think it would have to be some really awkward pseudo-operator that
throws an exception when it encounters its zero, and then reduce (or
something outside reduce) would catch that exception. Something like
that could be done but it would still be awkward. Don't wanna :)

You switched to a simpler operator. Would Haskell notice that

   def minabs(x, y): return min(x, y, key = abs)

has a meaningful zero? Surely it has its limits somewhere and then the
programmer needs to supply the information.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Search a sequence for its minimum and stop as soon as the lowest possible value is found

2017-01-07 Thread Steve D'Aprano
On Sat, 7 Jan 2017 01:04 am, Peter Otten wrote:

> Example: you are looking for the minimum absolute value in a series of
> integers. As soon as you encounter the first 0 it's unnecessary extra work
> to check the remaining values, but the builtin min() will continue.
> 
> The solution is a minimum function that allows the user to specify a stop
> value:
> 
 from itertools import count, chain
 stopmin(chain(reversed(range(10)), count()), key=abs, stop=0)
> 0
> 
> How would you implement stopmin()?

That depends on whether you want to stop when you find a value *equal* to
the stop value, or *less than* the stop value, or both.

It depends on whether you want to check for equality or check for any
arbitrary condition.

It depends on whether you want the stop value to be included or not. (It
looks like you do want it included.)

But I'd start with this:


# not tested
def stopmin(iterable, key=None, stop=None):
it = iter(iterable)
try:
smallest = next(it)
except StopIteration:
raise ValueError('empty iterable has no minimum')
else:
if key is not None:
keyed_smallest = key(smallest)
if key is None:
for x in iterable:
if x < smallest:
smallest = x
if x == stop:
break
else:
for x in iterable:
y = key(x)
if y < keyed_smallest:
keyed_smallest = y
smallest = x
if y == stop:
break
return smallest


Another possibility is to create a variant of itertools takewhile:

def takeuntil(predicate, iterable):
# takeuntil(lambda x: x<5, [1,4,6,4,1]) --> 1 4 6
for x in iterable:
yield x
if predicate(x):
break

min(takeuntil(lambda x: x == 0, iterable), key=abs)


py> from itertools import count, chain
py> iterable = chain(reversed(range(10)), count())
py> min(takeuntil(lambda x: x == 0, iterable), key=abs)
0
py> iterable = chain(range(-9, 10), count())
py> min(takeuntil(lambda x: x == 0, iterable), key=abs)
0




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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