Re: Spam

2017-10-03 Thread alister via Python-list

> They are literally criminals, they use computer viruses and malware to
> hijack people's computers to send their spam, and you want to trust them
> and buy from them?

this was probably a "Drive By" posy to get the original spam more 
attention & possibly bypass spam filters





-- 
Come live with me, and be my love,
And we will some new pleasures prove
Of golden sands, and crystal brooks,
With silken lines, and silver hooks.
-- John Donne
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-03 Thread Steve D'Aprano
On Tue, 3 Oct 2017 06:51 am, Bill wrote:

> Can you inspire me with a good decorator problem (standard homework
> exercise-level will be fine)?


Here is a nice even dozen problems for you. Please ask for clarification if any
are unclear.



(1) Write a decorator which simply prints a descriptive message and the name of
the decorated function once, when the function is first decorated.

E.g. if you write:

@decorate
def spam(x):
return x + 1  # for example

print(spam(1))
print(spam(2))


Python should print:

Decorating function spam.
2
3


Note: "spam" must not be hard-coded, it must be taken from the function being
decorated. (Hint: all functions have their name available as func.__name__.)


(2) Modify the decorator from (1) so that calling the wrapped function also
print a descriptive message such as "Calling function spam". The expected
output will be:

Decorating function spam.
Calling function spam.
2
Calling function spam.
3


(3) Write a decorator that checks that the decorated function's first argument
is a non-empty string, raising an appropriate exception if it is not, and lets
through any other arguments unchanged.


(4) Same as above, except the first argument is automatically stripped of
leading and trailing whitespace and forced to uppercase.


(5) Write a decorator which injects the argument 10 into the list of arguments
received by the wrapped function. E.g. if you write:

@inject
def add(a, b):
return a + b

@inject
def sub(a, b):
return a - b

print(add(5), sub(5))

Python should print "15 5". (And *not* "15 -5".)


(6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling
it what value to inject into the list of arguments:

@inject(99)
def sub(a, b):
return a - b

print(sub(5))

will now print "94".


(7) Write a decorator which checks the decorated function's two arguments are
given smallest first, swapping them around if needed.


(8) Write a decorator which prints the name of the wrapped function, its
arguments, and the time, each time the wrapped function is called.


(9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the
path to a file, and use the logging module to log the details to that file
instead of printing them.


(10) Write a decorator which adds an "cache" attribute initialised to an empty
dictionary to the decorated function.


(11) Write a decorator which wraps a class (not function!), and adds a "help"
method to the class which prints a message as shown below. For example:

@addhelp
class Spam:
pass

@addhelp
class Eggs:
pass

x = Spam()
x.help()
y = Eggs()
y.help()

will print:

See http://example.com/Spam
See http://example.com/Eggs

(Hint: classes also have a __name__ attribute.)


(12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator
from (10) above to each non-dunder¹ method in the class. That is, after:

@addcaches
class MyClass:
def foo(self):
pass
def bar(self):
pass

print(MyClass.foo.cache, MyClass.bar.cache)

should print "{} {}".



¹ Remember that dunder methods are those that start with two leading and
trailing underscores: "Double UNDERscore" methods.


* * *


Bruce Eckel has an excellent introduction to Python decorators, from way back
when they were first introduced in 2008. His introduction is notable because:

- he points out explicitly that Python decorators are not the same as 
  the Decorator design pattern (I thought they were!);

- he recommends using a class as the decorator, and building the extra
  functionality in object oriented fashion, rather than functional 
  programming fashion (this may give an easier introduction to those
  who aren't familiar with functional idioms);

- and he correctly predicted that the introduction of the @ syntactic
  sugar would have a big impact on the way people think about Python 
  code.


http://www.artima.com/weblogs/viewpost.jsp?thread=240808

Feel free to read his post before trying the problems I set.



-- 
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: INSTRUCTOR SOLUTIONS MANUAL Elementary Linear Algebra by Kuttler

2017-10-03 Thread fuad
Engineering Fluid Mechanics, 10th Edition by Crowe, Elger solution 
fuadnassa...@gmail.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-03 Thread Lele Gaifax
Steve D'Aprano  writes:

> (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying 
> the
> path to a file, and use the logging module to log the details to that file
> instead of printing them.

This may suffer of excessive creativity, as usually the details of *where* a
logger writes the messages are better left to a configuration done at another
level :)

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.

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


Re: newb question about @property

2017-10-03 Thread Steve D'Aprano
On Tue, 3 Oct 2017 10:01 pm, Lele Gaifax wrote:

> Steve D'Aprano  writes:
> 
>> (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying
>> the path to a file, and use the logging module to log the details to that
>> file instead of printing them.
> 
> This may suffer of excessive creativity, as usually the details of *where* a
> logger writes the messages are better left to a configuration done at another
> level :)

Right. I didn't say the path has to be hard-coded in the source.

@addlogging(config.logfile or default_logfile)
def function(x, y, z):
...


In production code, I'd probably pass a logger instance rather than a file name.

But in any case, its only a programming exercise, not meant to be
production-ready code.



-- 
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: newb question about @property

2017-10-03 Thread Ian Kelly
On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano
 wrote:
> On Tue, 3 Oct 2017 06:51 am, Bill wrote:
>
>> Can you inspire me with a good decorator problem (standard homework
>> exercise-level will be fine)?
>
>
> Here is a nice even dozen problems for you. Please ask for clarification if 
> any
> are unclear.
>
>
>
> (1) Write a decorator which simply prints a descriptive message and the name 
> of
> the decorated function once, when the function is first decorated.
>
> E.g. if you write:
>
> @decorate
> def spam(x):
> return x + 1  # for example
>
> print(spam(1))
> print(spam(2))
>
>
> Python should print:
>
> Decorating function spam.
> 2
> 3
>
>
> Note: "spam" must not be hard-coded, it must be taken from the function being
> decorated. (Hint: all functions have their name available as func.__name__.)
>
>
> (2) Modify the decorator from (1) so that calling the wrapped function also
> print a descriptive message such as "Calling function spam". The expected
> output will be:
>
> Decorating function spam.
> Calling function spam.
> 2
> Calling function spam.
> 3
>
>
> (3) Write a decorator that checks that the decorated function's first argument
> is a non-empty string, raising an appropriate exception if it is not, and lets
> through any other arguments unchanged.
>
>
> (4) Same as above, except the first argument is automatically stripped of
> leading and trailing whitespace and forced to uppercase.
>
>
> (5) Write a decorator which injects the argument 10 into the list of arguments
> received by the wrapped function. E.g. if you write:
>
> @inject
> def add(a, b):
> return a + b
>
> @inject
> def sub(a, b):
> return a - b
>
> print(add(5), sub(5))
>
> Python should print "15 5". (And *not* "15 -5".)
>
>
> (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument 
> telling
> it what value to inject into the list of arguments:
>
> @inject(99)
> def sub(a, b):
> return a - b
>
> print(sub(5))
>
> will now print "94".
>
>
> (7) Write a decorator which checks the decorated function's two arguments are
> given smallest first, swapping them around if needed.
>
>
> (8) Write a decorator which prints the name of the wrapped function, its
> arguments, and the time, each time the wrapped function is called.
>
>
> (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying 
> the
> path to a file, and use the logging module to log the details to that file
> instead of printing them.
>
>
> (10) Write a decorator which adds an "cache" attribute initialised to an empty
> dictionary to the decorated function.
>
>
> (11) Write a decorator which wraps a class (not function!), and adds a "help"
> method to the class which prints a message as shown below. For example:
>
> @addhelp
> class Spam:
> pass
>
> @addhelp
> class Eggs:
> pass
>
> x = Spam()
> x.help()
> y = Eggs()
> y.help()
>
> will print:
>
> See http://example.com/Spam
> See http://example.com/Eggs
>
> (Hint: classes also have a __name__ attribute.)
>
>
> (12) [ADVANCED] Write a decorator which wraps a class, and applies the 
> decorator
> from (10) above to each non-dunder¹ method in the class. That is, after:
>
> @addcaches
> class MyClass:
> def foo(self):
> pass
> def bar(self):
> pass
>
> print(MyClass.foo.cache, MyClass.bar.cache)
>
> should print "{} {}".
>
>
>
> ¹ Remember that dunder methods are those that start with two leading and
> trailing underscores: "Double UNDERscore" methods.

I also suggest:

(13) Modify the decorator from (8) so that the wrapper has the same
name and doc string as the wrapped function. (Hint: use
functools.wraps)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-03 Thread bartc

On 03/10/2017 15:39, Ian Kelly wrote:

On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano
 wrote:

On Tue, 3 Oct 2017 06:51 am, Bill wrote:


Can you inspire me with a good decorator problem (standard homework
exercise-level will be fine)?



Here is a nice even dozen problems for you. Please ask for clarification if any
are unclear.



(1) Write a decorator which simply prints a descriptive message and the name of
the decorated function once, when the function is first decorated.

E.g. if you write:

@decorate
def spam(x):
 return x + 1  # for example

print(spam(1))
print(spam(2))


Python should print:

Decorating function spam.
2
3


Note: "spam" must not be hard-coded, it must be taken from the function being
decorated. (Hint: all functions have their name available as func.__name__.)


(2) Modify the decorator from (1) so that calling the wrapped function also
print a descriptive message such as "Calling function spam". The expected
output will be:

Decorating function spam.
Calling function spam.
2
Calling function spam.
3


(3) Write a decorator that checks that the decorated function's first argument
is a non-empty string, raising an appropriate exception if it is not, and lets
through any other arguments unchanged.


(4) Same as above, except the first argument is automatically stripped of
leading and trailing whitespace and forced to uppercase.


(5) Write a decorator which injects the argument 10 into the list of arguments
received by the wrapped function. E.g. if you write:

@inject
def add(a, b):
 return a + b

@inject
def sub(a, b):
 return a - b

print(add(5), sub(5))

Python should print "15 5". (And *not* "15 -5".)


(6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling
it what value to inject into the list of arguments:

@inject(99)
def sub(a, b):
 return a - b

print(sub(5))

will now print "94".


(7) Write a decorator which checks the decorated function's two arguments are
given smallest first, swapping them around if needed.


(8) Write a decorator which prints the name of the wrapped function, its
arguments, and the time, each time the wrapped function is called.


(9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the
path to a file, and use the logging module to log the details to that file
instead of printing them.


(10) Write a decorator which adds an "cache" attribute initialised to an empty
dictionary to the decorated function.


(11) Write a decorator which wraps a class (not function!), and adds a "help"
method to the class which prints a message as shown below. For example:

@addhelp
class Spam:
 pass

@addhelp
class Eggs:
 pass

x = Spam()
x.help()
y = Eggs()
y.help()

will print:

See http://example.com/Spam
See http://example.com/Eggs

(Hint: classes also have a __name__ attribute.)


(12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator
from (10) above to each non-dunder¹ method in the class. That is, after:

@addcaches
class MyClass:
 def foo(self):
 pass
 def bar(self):
 pass

print(MyClass.foo.cache, MyClass.bar.cache)

should print "{} {}".



¹ Remember that dunder methods are those that start with two leading and
trailing underscores: "Double UNDERscore" methods.


[Sorry can't see Steve's original post.]

Does all this advanced stuff (which I don't understand and which doesn't 
look very appealing either; hopefully I will never come across such 
code) still count as programming?


It seems to me the equivalent of an advanced driving course teaching you 
how to customise your car rather than involving any actual driving.


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


when is filter test applied?

2017-10-03 Thread Neal Becker
In the following code (python3):

for rb in filter (lambda b : b in some_seq, seq):
  ... some code that might modify some_seq

I'm assuming that the test 'b in some_seq' is applied late, at the start of 
each iteration (but it doesn't seem to be working that way in my real code), 
so that if 'some_seq' is modified during a previous iteration the test is 
correctly performed on the latest version of 'some_seq' at the start of each 
iteration.  Is this correct, and is this guaranteed?


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


Re: newb question about @property

2017-10-03 Thread Jorge Gimeno
No, I see this as teaching the skills involved to drive a car. Practicing a
turn, scanning gauges, and checking blind spots are all a part of driving.
When one is learning, it's easier to learn these in isolation so when the
problem must be solved in real time, you know what to do. This is no
different. You may never need to use a decorator ever in your development
career, but the tool is there in case the problem you have can be elegantly
solved using one.

-Jorge

On Tue, Oct 3, 2017 at 8:00 AM, bartc  wrote:

> On 03/10/2017 15:39, Ian Kelly wrote:
>
>> On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano
>>  wrote:
>>
>>> On Tue, 3 Oct 2017 06:51 am, Bill wrote:
>>>
>>> Can you inspire me with a good decorator problem (standard homework
 exercise-level will be fine)?

>>>
>>>
>>> Here is a nice even dozen problems for you. Please ask for clarification
>>> if any
>>> are unclear.
>>>
>>>
>>>
>>> (1) Write a decorator which simply prints a descriptive message and the
>>> name of
>>> the decorated function once, when the function is first decorated.
>>>
>>> E.g. if you write:
>>>
>>> @decorate
>>> def spam(x):
>>>  return x + 1  # for example
>>>
>>> print(spam(1))
>>> print(spam(2))
>>>
>>>
>>> Python should print:
>>>
>>> Decorating function spam.
>>> 2
>>> 3
>>>
>>>
>>> Note: "spam" must not be hard-coded, it must be taken from the function
>>> being
>>> decorated. (Hint: all functions have their name available as
>>> func.__name__.)
>>>
>>>
>>> (2) Modify the decorator from (1) so that calling the wrapped function
>>> also
>>> print a descriptive message such as "Calling function spam". The expected
>>> output will be:
>>>
>>> Decorating function spam.
>>> Calling function spam.
>>> 2
>>> Calling function spam.
>>> 3
>>>
>>>
>>> (3) Write a decorator that checks that the decorated function's first
>>> argument
>>> is a non-empty string, raising an appropriate exception if it is not,
>>> and lets
>>> through any other arguments unchanged.
>>>
>>>
>>> (4) Same as above, except the first argument is automatically stripped of
>>> leading and trailing whitespace and forced to uppercase.
>>>
>>>
>>> (5) Write a decorator which injects the argument 10 into the list of
>>> arguments
>>> received by the wrapped function. E.g. if you write:
>>>
>>> @inject
>>> def add(a, b):
>>>  return a + b
>>>
>>> @inject
>>> def sub(a, b):
>>>  return a - b
>>>
>>> print(add(5), sub(5))
>>>
>>> Python should print "15 5". (And *not* "15 -5".)
>>>
>>>
>>> (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument
>>> telling
>>> it what value to inject into the list of arguments:
>>>
>>> @inject(99)
>>> def sub(a, b):
>>>  return a - b
>>>
>>> print(sub(5))
>>>
>>> will now print "94".
>>>
>>>
>>> (7) Write a decorator which checks the decorated function's two
>>> arguments are
>>> given smallest first, swapping them around if needed.
>>>
>>>
>>> (8) Write a decorator which prints the name of the wrapped function, its
>>> arguments, and the time, each time the wrapped function is called.
>>>
>>>
>>> (9) [ADVANCED] Modify the decorator from (8) to take an argument
>>> specifying the
>>> path to a file, and use the logging module to log the details to that
>>> file
>>> instead of printing them.
>>>
>>>
>>> (10) Write a decorator which adds an "cache" attribute initialised to an
>>> empty
>>> dictionary to the decorated function.
>>>
>>>
>>> (11) Write a decorator which wraps a class (not function!), and adds a
>>> "help"
>>> method to the class which prints a message as shown below. For example:
>>>
>>> @addhelp
>>> class Spam:
>>>  pass
>>>
>>> @addhelp
>>> class Eggs:
>>>  pass
>>>
>>> x = Spam()
>>> x.help()
>>> y = Eggs()
>>> y.help()
>>>
>>> will print:
>>>
>>> See http://example.com/Spam
>>> See http://example.com/Eggs
>>>
>>> (Hint: classes also have a __name__ attribute.)
>>>
>>>
>>> (12) [ADVANCED] Write a decorator which wraps a class, and applies the
>>> decorator
>>> from (10) above to each non-dunder¹ method in the class. That is, after:
>>>
>>> @addcaches
>>> class MyClass:
>>>  def foo(self):
>>>  pass
>>>  def bar(self):
>>>  pass
>>>
>>> print(MyClass.foo.cache, MyClass.bar.cache)
>>>
>>> should print "{} {}".
>>>
>>>
>>>
>>> ¹ Remember that dunder methods are those that start with two leading and
>>> trailing underscores: "Double UNDERscore" methods.
>>>
>>
> [Sorry can't see Steve's original post.]
>
> Does all this advanced stuff (which I don't understand and which doesn't
> look very appealing either; hopefully I will never come across such code)
> still count as programming?
>
> It seems to me the equivalent of an advanced driving course teaching you
> how to customise your car rather than involving any actual driving.
>
> --
> bartc
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: when is filter test applied?

2017-10-03 Thread Paul Moore
My intuition is that the lambda creates a closure that captures the
value of some_seq. If that value is mutable, and "modify some_seq"
means "mutate the value", then I'd expect each element of seq to be
tested against the value of some_seq that is current at the time the
test occurs, i.e. when the entry is generated from the filter.

You say that doesn't happen, so my intuition (and yours) seems to be
wrong. Can you provide a reproducible test case? I'd be inclined to
run that through dis.dis to see what bytecode was produced.

Paul

On 3 October 2017 at 16:08, Neal Becker  wrote:
> In the following code (python3):
>
> for rb in filter (lambda b : b in some_seq, seq):
>   ... some code that might modify some_seq
>
> I'm assuming that the test 'b in some_seq' is applied late, at the start of
> each iteration (but it doesn't seem to be working that way in my real code),
> so that if 'some_seq' is modified during a previous iteration the test is
> correctly performed on the latest version of 'some_seq' at the start of each
> iteration.  Is this correct, and is this guaranteed?
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Research paper "Energy Efficiency across Programming Languages: How does energy, time, and memory relate?"

2017-10-03 Thread 3.1415926535897932384626433832795
The page is fixed BTW
>>>import this

On Sun, Sep 17, 2017 at 6:13 AM,  wrote:

> Send Python-list mailing list submissions to
> python-list@python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://mail.python.org/mailman/listinfo/python-list
> or, via email, send a message with subject or body 'help' to
> python-list-requ...@python.org
>
> You can reach the person managing the list at
> python-list-ow...@python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Python-list digest..."
>
> Today's Topics:
>
>1. Re: Old Man Yells At Cloud (Dennis Lee Bieber)
>2. Re: Old Man Yells At Cloud (Stefan Ram)
>3. Re: Which database system? (Stefan Ram)
>4. CPython has hit 100,000 commits (breamore...@gmail.com)
>5. [RELEASE] Python 2.7.14 (Benjamin Peterson)
>6. Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?"
>   (breamore...@gmail.com)
>7. Re: Old Man Yells At Cloud (Steve D'Aprano)
>8. Re: Old Man Yells At Cloud (John Pote)
>9. Re: Old Man Yells At Cloud (Steve D'Aprano)
>   10. Re: Old Man Yells At Cloud (MRAB)
>   11. Re: Old Man Yells At Cloud (Chris Angelico)
>   12. Re: Old Man Yells At Cloud (Chris Angelico)
>   13. Re: Old Man Yells At Cloud (Dennis Lee Bieber)
>   14. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Steve
> D'Aprano)
>   15. Re: Old Man Yells At Cloud (Stefan Ram)
>   16. Re: Old Man Yells At Cloud (Paul Rubin)
>   17. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Ian Kelly)
>   18. Re: Old Man Yells At Cloud (Stefan Ram)
>   19. Re: ttk.Notebook Tabs Question (Abdur-Rahmaan Janhangeer)
>   20. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Terry Reedy)
>   21. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Chris
> Angelico)
>   22. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Terry Reedy)
>   23. Re: Old Man Yells At Cloud (Gregory Ewing)
>   24. Re: Old Man Yells At Cloud (Gregory Ewing)
>   25. Re: Old Man Yells At Cloud (mm0fmf)
>   26. Re: Old Man Yells At Cloud (Steve D'Aprano)
>   27. Re: Research paper "Energy Efficiency across Programming
>   Languages: How does energy, time, and memory relate?" (Steve
> D'Aprano)
>   28. Re: Which database system? (Amirouche Boubekki)
>   29. Typo-squatting PyPi (Alain Ketterlin)
>   30. Re: Old Man Yells At Cloud (Leam Hall)
>   31. Re: Old Man Yells At Cloud (Abdur-Rahmaan Janhangeer)
>   32. speech_to_text python command not working (pizza python)
>   33. Re: Old Man Yells At Cloud (Leam Hall)
>   34. Re: Old Man Yells At Cloud (Chris Angelico)
>   35. Python built-ins versus Javascript [was Re: Old Man Yells At
>   Cloud] (Steve D'Aprano)
>   36. Re: Old Man Yells At Cloud (Steve D'Aprano)
>   37. Unicode (was: Old Man Yells At Cloud) (Leam Hall)
>   38. Re: Unicode (was: Old Man Yells At Cloud) (Paul Moore)
>   39. Re: Unicode (was: Old Man Yells At Cloud) (Chris Angelico)
>   40. Re: Unicode (Leam Hall)
>   41. Re: Old Man Yells At Cloud (Steve D'Aprano)
>   42. Re: Unicode (Peter Otten)
>
>
> -- Forwarded message --
> From: Dennis Lee Bieber 
> To: python-list@python.org
> Cc:
> Bcc:
> Date: Sat, 16 Sep 2017 12:52:59 -0400
> Subject: Re: Old Man Yells At Cloud
> On Sat, 16 Sep 2017 09:59:43 -0500, Tim Daneliuk 
> declaimed the following:
>
>
>
> >Well, the whole integer floor division thing years ago was the beginning
> >of the end - Python was doomed ...
>
> Yes -- that would give me fits if I were using Python3 currently...
> Since so many of the languages I've learned over the past years use the
> concept integer / integer => integer_result
>
> Come to think of it -- wasn't there a post from someone (seems to
> expired or been filtered from my client) asking for help with some sorting
> program... I'm pretty sure the partitioning logic would croak on Python3
> due to floating point results in the slice indices:
>
> pA = part[:n/2]
> pB = part[n/2:]
>
> --
> Wulfraed Dennis Lee Bieber AF6VN
> wlfr...@ix.netcom.comHTTP://wlfraed.home.netcom.com/
>
>
>
>
> -- Forwarded message --
> From: Stefan Ram 
> To: python-list@python.org
> Cc:
> Bcc:
> Date: 16 Sep 2017 18:00:00 GMT
> Subject: Re: Old Man Yells At Cloud
> Steve D'Aprano  writes:
> >"Hi, I've been programming in Python for what seems like days now, and
> here's
> >all the things that you guys are doing wrong.
>
>   I never ever have written a line of Python 2. I started with
>   Python 3.6.0. Yet 

Re: when is filter test applied?

2017-10-03 Thread Neal Becker
I'm not certain that it isn't behaving as expected - my code is quite
complicated.

On Tue, Oct 3, 2017 at 11:35 AM Paul Moore  wrote:

> My intuition is that the lambda creates a closure that captures the
> value of some_seq. If that value is mutable, and "modify some_seq"
> means "mutate the value", then I'd expect each element of seq to be
> tested against the value of some_seq that is current at the time the
> test occurs, i.e. when the entry is generated from the filter.
>
> You say that doesn't happen, so my intuition (and yours) seems to be
> wrong. Can you provide a reproducible test case? I'd be inclined to
> run that through dis.dis to see what bytecode was produced.
>
> Paul
>
> On 3 October 2017 at 16:08, Neal Becker  wrote:
> > In the following code (python3):
> >
> > for rb in filter (lambda b : b in some_seq, seq):
> >   ... some code that might modify some_seq
> >
> > I'm assuming that the test 'b in some_seq' is applied late, at the start
> of
> > each iteration (but it doesn't seem to be working that way in my real
> code),
> > so that if 'some_seq' is modified during a previous iteration the test is
> > correctly performed on the latest version of 'some_seq' at the start of
> each
> > iteration.  Is this correct, and is this guaranteed?
> >
> >
> > --
> > https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: when is filter test applied?

2017-10-03 Thread Peter Otten
Neal Becker wrote:

> In the following code (python3):
> 
> for rb in filter (lambda b : b in some_seq, seq):
>   ... some code that might modify some_seq
> 
> I'm assuming that the test 'b in some_seq' is applied late, at the start
> of each iteration (but it doesn't seem to be working that way in my real
> code), so that if 'some_seq' is modified during a previous iteration the
> test is correctly performed on the latest version of 'some_seq' at the
> start of each
> iteration.  Is this correct, and is this guaranteed?

Yes. filter() is lazy in Python 3, and otherwise the usual rules for 
binding, mutating, and lookup of some_seq apply. Example:

>>> some_seq = set("abc")
>>> for c in filter(lambda x: x in some_seq, "abbbcccCAAA"):
... some_seq.remove(c)
... 
>>> some_seq = set("abc")
>>> for c in filter(lambda x: x in some_seq, "abbbcccCAAA"):
... print(c)
... some_seq.remove(c)
... if not some_seq: some_seq = set("ABC")
... 
a
b
c  # at that point some_seq will be bound to a new set("ABC")
C
B
A  # as above
A


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


Re: when is filter test applied?

2017-10-03 Thread Paul Moore
On 3 October 2017 at 16:38, Neal Becker  wrote:
> I'm not certain that it isn't behaving as expected - my code is quite
> complicated.

OK, so I'd say the filtering would follow any changes made to some_seq
- not because it's a documented guarantee as such, but simply as a
consequence of the behaviour of generators and closures.

I'd tend to steer clear of code that relied on that behaviour in
practice, as I think it's likely to be hard to understand/maintain,
but I'm aware that reality's never quite that simple :-)

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


Re: optional int- and float arguments

2017-10-03 Thread Chris Angelico
On Wed, Oct 4, 2017 at 3:18 AM, Stefan Ram  wrote:
>   »int« and »float« seem to behave quite similar:
>
> |>>> int( x = 8 )
> |8
> |>>> float( x = 8.0 )
> |8.0
> |>>> int()
> |0
> |>>> float()
> |0.0
>
>   . Yet the ways their parameters are being documented in
>   "The Python Library Reference, Release 3.6.0" seem to differ:
>
> |class float([x])
> |class int(x=0)
>

Huh. I just checked help() in Python 3.7, and it's the other way around.

 |  float(x=0, /)
 |  int([x]) -> integer

>   Would there be any error in describing »float« using
>
> |class float(x=0.0)
>
>   ?

I don't think so. This is a strange inconsistency in the docs, given
that they behave the same way. Would be worth opening a tracker issue,
mentioning all four things you found.

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


Re: The "loop and a half"

2017-10-03 Thread Rhodri James

On 03/10/17 18:29, Stefan Ram wrote:

   Is this the best way to write a "loop and a half" in Python?


Define "best".


x = 1
while x:
 x = int( input( "Number (enter 0 to terminate)? " ))
 if x:
 print( f'Square = { x**2 }' )


I'd usually write it as

while True:
  x = tedious_function_call_with_sentinel()
  if x == 0:
break
  do_something_with(x)

...or alternatively

x = tedious_function_call_with_sentinel()
while x != 0:
  do_something_with(x)
  x = tedious_function_call_with_sentinel()

...or some other refactoring.


   In a C-like language, one could write:

while x = int( input( "Number (enter 0 to terminate)? " ))
 print( f'Square = { x**2 }' )


One could.  One would richly deserve the compiler warnings one got as a 
result, but one could.


--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-03 Thread Peter Otten
Stefan Ram wrote:

>   Is this the best way to write a "loop and a half" in Python?
> 
> x = 1
> while x:
> x = int( input( "Number (enter 0 to terminate)? " ))
> if x:
> print( f'Square = { x**2 }' )
> 
>   In a C-like language, one could write:
> 
> while x = int( input( "Number (enter 0 to terminate)? " ))
> print( f'Square = { x**2 }' )

Use iter() and a for loop:

>>> def input_int():
... return int(input("Enter number (0 to terminate): "))
... 
>>> for x in iter(input_int, 0):
... print(f"Square = { x**2 }")
... 
Enter number (0 to terminate): 1
Square = 1
Enter number (0 to terminate): 2
Square = 4
Enter number (0 to terminate): 0
>>> 


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


Re: The "loop and a half"

2017-10-03 Thread Thomas Jollans
On 03/10/17 20:05, Dennis Lee Bieber wrote:
>
> while True:
>   x = input("Enter a number (blank to exit) => ")
>   if x:
>   try:
>   ix = int(x)
>   print("Square = %s" % (ix * ix) ) #why invoke 
> exponential
>   except checkTheDocsForException:

The nice thing about how the stdlib does exceptions is that you can be
pretty certain that this has simply got to be a ValueError. It's still
best to check (or, in this case, try it out) - but you just know that
there's nothing else it can be.

>   print(" '%s' is not a valid integer" % x )
>   else:
>   break


PS: I was weak. I tried it out before sending this mail.


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


F5 not working?

2017-10-03 Thread Breta Skinner
Hello,
I tried looking around the website, but didn't see a question about
function keys.
Somehow, I "turned off" the F5 function in the IDLE. It no longer "run
module", but just does nothing. I have downloaded the newest version, 3.7,
but that did not solve the problem.  I admit to being clumsy, so I'm
guessing I hit an odd key combination which disabled F5 for Python IDLE on
this machine (windows 64 bit HP desk top).
I tried to check the configuration, but it looks like the key is set up:
[image: Inline image 1]
Any suggestions?  It was nice to have the key working.
Thanks,
Breta.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-03 Thread Bill

Steve D'Aprano wrote:

On Tue, 3 Oct 2017 06:51 am, Bill wrote:


Can you inspire me with a good decorator problem (standard homework
exercise-level will be fine)?


Here is a nice even dozen problems for you. Please ask for clarification if any
are unclear.


Thank you for sharing the problems on decorators!   I just finished 
reading Bruce Eckels' note on decorators (as well as some of the 
comments left by readers), which you shared a link to, and found the 
whole discussion very informative. If I was to point to two details, the 
analogy of decorator's with macros is helpful to bear in mind, as is the 
remark that "@Wrapper(def f..)" reassigns f to the composition. With the 
latter unstated, the matter can cause confusion!   %-)


Bill





(1) Write a decorator which simply prints a descriptive message and the name of
the decorated function once, when the function is first decorated.

E.g. if you write:

@decorate
def spam(x):
 return x + 1  # for example

print(spam(1))
print(spam(2))


Python should print:

Decorating function spam.
2
3


Note: "spam" must not be hard-coded, it must be taken from the function being
decorated. (Hint: all functions have their name available as func.__name__.)


(2) Modify the decorator from (1) so that calling the wrapped function also
print a descriptive message such as "Calling function spam". The expected
output will be:

Decorating function spam.
Calling function spam.
2
Calling function spam.
3


(3) Write a decorator that checks that the decorated function's first argument
is a non-empty string, raising an appropriate exception if it is not, and lets
through any other arguments unchanged.


(4) Same as above, except the first argument is automatically stripped of
leading and trailing whitespace and forced to uppercase.


(5) Write a decorator which injects the argument 10 into the list of arguments
received by the wrapped function. E.g. if you write:

@inject
def add(a, b):
 return a + b

@inject
def sub(a, b):
 return a - b

print(add(5), sub(5))

Python should print "15 5". (And *not* "15 -5".)


(6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling
it what value to inject into the list of arguments:

@inject(99)
def sub(a, b):
 return a - b

print(sub(5))

will now print "94".


(7) Write a decorator which checks the decorated function's two arguments are
given smallest first, swapping them around if needed.


(8) Write a decorator which prints the name of the wrapped function, its
arguments, and the time, each time the wrapped function is called.


(9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the
path to a file, and use the logging module to log the details to that file
instead of printing them.


(10) Write a decorator which adds an "cache" attribute initialised to an empty
dictionary to the decorated function.


(11) Write a decorator which wraps a class (not function!), and adds a "help"
method to the class which prints a message as shown below. For example:

@addhelp
class Spam:
 pass

@addhelp
class Eggs:
 pass

x = Spam()
x.help()
y = Eggs()
y.help()

will print:

See http://example.com/Spam
See http://example.com/Eggs

(Hint: classes also have a __name__ attribute.)


(12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator
from (10) above to each non-dunder¹ method in the class. That is, after:

@addcaches
class MyClass:
 def foo(self):
 pass
 def bar(self):
 pass

print(MyClass.foo.cache, MyClass.bar.cache)

should print "{} {}".



¹ Remember that dunder methods are those that start with two leading and
trailing underscores: "Double UNDERscore" methods.


* * *


Bruce Eckel has an excellent introduction to Python decorators, from way back
when they were first introduced in 2008. His introduction is notable because:

- he points out explicitly that Python decorators are not the same as
   the Decorator design pattern (I thought they were!);

- he recommends using a class as the decorator, and building the extra
   functionality in object oriented fashion, rather than functional
   programming fashion (this may give an easier introduction to those
   who aren't familiar with functional idioms);

- and he correctly predicted that the introduction of the @ syntactic
   sugar would have a big impact on the way people think about Python
   code.


http://www.artima.com/weblogs/viewpost.jsp?thread=240808

Feel free to read his post before trying the problems I set.





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


Re: F5 not working?

2017-10-03 Thread Terry Reedy

On 10/3/2017 2:02 PM, Breta Skinner wrote:

Hello,
I tried looking around the website, but didn't see a question about
function keys.
Somehow, I "turned off" the F5 function in the IDLE. It no longer "run
module", but just does nothing. I have downloaded the newest version, 3.7,
but that did not solve the problem.  I admit to being clumsy, so I'm
guessing I hit an odd key combination which disabled F5 for Python IDLE on
this machine (windows 64 bit HP desk top).
I tried to check the configuration, but it looks like the key is set up:
[image: Inline image 1]


This is text only list; images are discarded.  If you run IDLE, select 
Options => Preferences => Keys and scroll down to 'run-module', it will 
will say  for a built-in keyset until you have changed 
idlelib/config-keys.def and should say  for custom key sets 
until you changed it, in which case, you should be able to change it back.


If it says F5, which is perhaps what you meant above, and F5 does not 
work, then you might have changed your keyboard, outside of IDLE, so 
that it does not generate the expected keycode.


Have you rebooted?


Any suggestions?  It was nice to have the key working.


--
Terry Jan Reedy

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


Re: The "loop and a half"

2017-10-03 Thread Bill

Stefan Ram wrote:

   Is this the best way to write a "loop and a half" in Python?


Is your goal brevity or clarity, or something else (for instance, what 
does the code written by the other members of your "team" look 
like--woudn't it be nice if it matched)?


Bill



x = 1
while x:
 x = int( input( "Number (enter 0 to terminate)? " ))
 if x:
 print( f'Square = { x**2 }' )

   In a C-like language, one could write:

while x = int( input( "Number (enter 0 to terminate)? " ))
 print( f'Square = { x**2 }' )

   .



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


Need some help with argparse

2017-10-03 Thread Kryptxy via Python-list
Hi,
I am trying to figure out something with argparse.
Here is a scenario:

I have a group of arguments, say: (-a, -b, -c, -d, -e) [lets call it group1]
I have another group, say: (-z, -y, -x, -w) [lets call it group2]

Code:
import argparse
parser = argparse.ArgumentParser(description="Test this shiz")
group1= parser.add_argument_group("Group 1")
group2= parser.add_argument_group("Group 2")

group1.add_argument('-a', '--extendA', action="store_true", help="HELP")
group1.add_argument('-b', '--extendB', action="store_true", help="HELP")
group1.add_argument('-c', '--extendC', action="store_true", help="HELP")
group1.add_argument('-d', '--extendD', action="store_true", help="HELP")
group1.add_argument('-e', '--extendE', action="store_true", help="HELP")

# Similarly for group 2:
group2.add_argument('-z', '--extendZ', action="store_true", help="HELP")
group2.add_argument('-y', '--extendY', action="store_true", help="HELP")
group2.add_argument('-x', '--extendX', action="store_true", help="HELP")
group2.add_argument('-w', '--extendW', action="store_true", help="HELP")

args = parser.parse_args()

Now I want to get arguments of group1 and group2 separately.
If I print(args) - I get arguments from both the groups.
Also group1.parse_args() does not work (since ArgumentGroup does not have 
parse_args() method)

How can I get all arguments of group 1 ONLY? Same goes for group 2?
I tried subparsers too - but they require a mandatory `positional argument` - 
which is not application's requirement.

Any kind of help is appreciated.
Thank you!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Need some help with argparse

2017-10-03 Thread Ben Finney
Kryptxy via Python-list  writes:

> I have a group of arguments, say: (-a, -b, -c, -d, -e) [lets call it group1]
> I have another group, say: (-z, -y, -x, -w) [lets call it group2]

Argument groups are a feature to control the help output from the
parser:

 When an argument is added to the group, the parser treats it just
 like a normal argument, but displays the argument in a separate
 group for help messages.

 https://docs.python.org/3/library/argparse.html#argument-groups>

> Now I want to get arguments of group1 and group2 separately.

You don't want to use the “argument groups” feature for that, because
that's not what it does.

> How can I get all arguments of group 1 ONLY? Same goes for group 2?
> I tried subparsers too - but they require a mandatory `positional
> argument` - which is not application's requirement.

I don't know of a way to have the argument parser know the separation
you're talking about, without using a subparser.

You will need to maintain that separation yourself, outside the parser.

One simple way (I have not tried this)::

argument_names_by_group = {
'foo': {'lorem', 'donec', 'fusce'},
'bar': {'aliquam', 'nunc'},
}

args = parser.parse_args()

args_by_group = {
group_name: {
getattr(arg_name)
for arg_name in argument_names_by_group[group_name]
}
for group_name in argument_names_by_group
}

-- 
 \ “I believe our future depends powerfully on how well we |
  `\ understand this cosmos, in which we float like a mote of dust |
_o__) in the morning sky.” —Carl Sagan, _Cosmos_, 1980 |
Ben Finney

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


[RELEASE] Python 3.6.3 is now available

2017-10-03 Thread Ned Deily
On behalf of the Python development community and the Python 3.6
release team, I am happy to announce the availability of Python 3.6.3,
the third maintenance release of Python 3.6.  Detailed information
about the changes made in 3.6.3 can be found in the change log here:

https://docs.python.org/3.6/whatsnew/changelog.html#python-3-6-3-final

Please see "What’s New In Python 3.6" for more information about the
new features in Python 3.6:

https://docs.python.org/3.6/whatsnew/3.6.html

You can download Python 3.6.3 here:

https://www.python.org/downloads/release/python-363/

The next maintenance release of Python 3.6 is expected to follow in
about 3 months, around the end of 2017-12.  More information about the
3.6 release schedule can be found here:

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

Enjoy!

--
  Ned Deily
  n...@python.org -- []

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


Re: when is the filter test applied?

2017-10-03 Thread ROGER GRAYDON CHRISTMAN
On Tue, Oct  3, 2017 15:38:42, Neal Becker  wrote:
>
I'm not certain that it isn't behaving as expected - my code is quite
>complicated.
>
>On Tue, Oct 3, 2017 at 11:35 AM Paul Moore  wrote:
>
>> My intuition is that the lambda creates a closure that captures the
>> value of some_seq. If that value is mutable, and "modify some_seq"
>> means "mutate the value", then I'd expect each element of seq to be
>> tested against the value of some_seq that is current at the time the
>> test occurs, i.e. when the entry is generated from the filter.
>>
>> You say that doesn't happen, so my intuition (and yours) seems to be
>> wrong. Can you provide a reproducible test case? I'd be inclined to
>> run that through dis.dis to see what bytecode was produced.
>>
>> Paul
>>
>> On 3 October 2017 at 16:08, Neal Becker  wrote:
>> > In the following code (python3):
>> >
>> > for rb in filter (lambda b : b in some_seq, seq):
>> >   ... some code that might modify some_seq
>> >
>> > I'm assuming that the test 'b in some_seq' is applied late, at the start of
>> > each iteration (but it doesn't seem to be working that way in my real
code),
>> > so that if 'some_seq' is modified during a previous iteration the test is
>> > correctly performed on the latest version of 'some_seq' at the start of
each
>> > iteration.  Is this correct, and is this guaranteed?
>
>

I think one must always be very careful about modifying anything
that you are iterating across -- if not avoiding that sort of thing entirely.
In particular, avoid anything that might add or remove elements
in the middle of the sequence.

YMMV, but you can imagine the iterator behaving like some of these
(all naturally implementation-dependent)

Traversing an indexable sequence (such as a list or string)
might maintain an internal counter that increments for each iteration.
Traversing a linked sequence (such as a linked list)
might maintain an internal reference that advances down the chain.
If you were to remove the element that you were currently visiting
(such was done in   "for c in x:   x.remove(c)")) you may end up
missing items.   For example, if you remove element 10 from a 
list or string, element 11 moves forward to position 10, but the
internal counter mentioned above would still advance to 11 --
skipping over the item that followed what you removed.
Similarly, if you to remove the linked list node that contained
the data you tried to remove, you might have an unspecified
behavior of where the linked list advancement would take you.

It would be safer to make a deep copy of the data iterable data
and iterate down the copy, so you can be sure that all your 
intended changes to the original data do not interfere with 
your iteration.

Here is an illustration of something going awry:
('.'s added in case my mailer destroys indents)
x = list('aaabcadaae')

for c in x:

...  if c == 'a':

...   x.remove('a')
''.join(x)
'bcaadaae'
Of the original 18 a's, 10 were removed.
The test for (c == 'a') only applied to every other a,
because the deletions removed some a's forward,
while the iterator kept advancing.
(And of course, it always deleted the first a in the list,
even if that is not where my iterator was looking)


And yes, I would expect the filter to be a lazy application
to the iterable you are filtering, so anything that removes
from your iterable is going to cause you filter so skip something.
That can also be fixed by copying the iterable first.

Or alternatively, you can go more functional and instead
create a new iterable set of data from the old, instead of
mutating what you have.

Roger Christman
Pennsylvania State University


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


Re: when is the filter test applied?

2017-10-03 Thread Chris Angelico
On Wed, Oct 4, 2017 at 7:31 AM, ROGER GRAYDON CHRISTMAN  wrote:
>>> > for rb in filter (lambda b : b in some_seq, seq):
>>> >   ... some code that might modify some_seq
> I think one must always be very careful about modifying anything
> that you are iterating across -- if not avoiding that sort of thing entirely.
> In particular, avoid anything that might add or remove elements
> in the middle of the sequence.

It isn't, though. That's iterating over seq, and possibly modifying
some_seq. So it's safe.

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


testbank

2017-10-03 Thread Patty Kramer
do you have testbank for Small Business Management: Launching & Growing 
Entrepreneurial Ventures, 18th Edition by Justin G. LongeneckerJ. William Petty 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 04:45 am, Rhodri James wrote:

> On 03/10/17 18:29, Stefan Ram wrote:
>>Is this the best way to write a "loop and a half" in Python?
> 
> Define "best".

I'd start with "define loop and a half".





-- 
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: The "loop and a half"

2017-10-03 Thread Terry Reedy

On 10/3/2017 2:10 PM, Peter Otten wrote:

Stefan Ram wrote:


   Is this the best way to write a "loop and a half" in Python?


[snip while loop]


Use iter() and a for loop:


def input_int():

... return int(input("Enter number (0 to terminate): "))
...

for x in iter(input_int, 0):

... print(f"Square = { x**2 }")
...
Enter number (0 to terminate): 1
Square = 1
Enter number (0 to terminate): 2
Square = 4
Enter number (0 to terminate): 0


I think this is the best answer.  Using a for loop cleanly separates the 
source of a sequence of objects from processing the objects.  While loop 
 raret in Python as they are only needed for other patterns, such as 
'while mutable object is not in the state we want: modify some more', 
and the number of modifications needed is not necessarity known ahead of 
time.


--
Terry Jan Reedy

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


Re: optional int- and float arguments

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 03:18 am, Stefan Ram wrote:

>   »int« and »float« seem to behave quite similar:
> 
> |>>> int( x = 8 )
> |8
> |>>> float( x = 8.0 )
> |8.0


I expect that these functions taking a *named* parameter "x" is an accident that
shouldn't be relied on.


-- 
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: newb question about @property

2017-10-03 Thread Ian Kelly
On Tue, Oct 3, 2017 at 9:16 AM, Jorge Gimeno  wrote:
> No, I see this as teaching the skills involved to drive a car. Practicing a
> turn, scanning gauges, and checking blind spots are all a part of driving.
> When one is learning, it's easier to learn these in isolation so when the
> problem must be solved in real time, you know what to do. This is no
> different. You may never need to use a decorator ever in your development
> career, but the tool is there in case the problem you have can be elegantly
> solved using one.

I have to agree. Learning the language without taking the time to
learn all of its features is like learning to drive without bothering
to learn how to use the tachometer or the hand brake. Sure you can
drive without those things, but that doesn't make them not useful.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-03 Thread Larry Hudson via Python-list

On 10/03/2017 10:29 AM, Stefan Ram wrote:

   Is this the best way to write a "loop and a half" in Python?

x = 1
while x:
 x = int( input( "Number (enter 0 to terminate)? " ))
 if x:
 print( f'Square = { x**2 }' )

   In a C-like language, one could write:

while x = int( input( "Number (enter 0 to terminate)? " ))
 print( f'Square = { x**2 }' )



This does not answer your question and is only somewhat related.

Here is a generic number input function that I wrote for my own (hobby-programmer) use.  The 
docstring explains it.



def get_num(prmt, lo=None, hi=None, dflt=None, flt=False, abrt=False):
"""Get a number from the console

Parameters:
prmt:   The prompt to be used with the input function, required.
lo: The minimum permissible value, or None if no minimum (the 
default)
hi: The maximum permissible value, or None if no maximum (the 
default)
dflt:   Default value to return with empty input, None is no default 
value
flt:If True, accepts and returns floats
If False, accepts and returns integers (the default)
abrt:   If True empty input aborts and returns None
If False (the default) empty input is handled as invalid data

Invalid input or out-of-range values are not accepted and a warning message
is displayed.  It will then repeat the input prompt for a new value.
Note:  If the dflt parameter is given, its data type is not checked and
could be anything, and could also be used as an abort signal.
"""

while True:
val = input(prmt).strip()
if not val:
if abrt:
return None
if dflt is not None:
return dflt
try:
num = float(val) if flt else int(val)
except ValueError:
print('Invalid input, try again')
continue
#   We have a valid number here, check for in-range
if (lo is None or num >= lo) and (hi is None or num <= hi):
return num
print('Number is out of range')
--

FWIW, as to your question, my preference is for the pseudo-do loop using 'while True' with a 
break as described in other answers here.


Using this function, your loop could be:

while True:
x = get_num('Number (enter ) to terminate:  ')
if x == 0:  #  Or if not x:
break
print(f'Square = { x**2 }')

OR my preference:  Use empty input to terminate by making the input and test:
x = get_num('Number ( to terminate:  ', abrt=True)
if x is None:
break

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


Re: The "loop and a half"

2017-10-03 Thread Chris Angelico
On Wed, Oct 4, 2017 at 1:17 PM, Larry Hudson via Python-list
 wrote:
> def get_num(prmt, lo=None, hi=None, dflt=None, flt=False, abrt=False):
> """Get a number from the console
>
> Parameters:
> prmt:   The prompt to be used with the input function, required.
> lo: The minimum permissible value, or None if no minimum (the
> default)
> hi: The maximum permissible value, or None if no maximum (the
> default)
> dflt:   Default value to return with empty input, None is no default
> value
> flt:If True, accepts and returns floats
> If False, accepts and returns integers (the default)
> abrt:   If True empty input aborts and returns None
> If False (the default) empty input is handled as invalid
> data
>
> Invalid input or out-of-range values are not accepted and a warning
> message
> is displayed.  It will then repeat the input prompt for a new value.
> Note:  If the dflt parameter is given, its data type is not checked and
> could be anything, and could also be used as an abort signal.
> """
>
> while True:
> val = input(prmt).strip()
> if not val:
> if abrt:
> return None
> if dflt is not None:
> return dflt
> try:
> num = float(val) if flt else int(val)
> except ValueError:
> print('Invalid input, try again')
> continue
> #   We have a valid number here, check for in-range
> if (lo is None or num >= lo) and (hi is None or num <= hi):
> return num
> print('Number is out of range')

You know, you don't HAVE to economize on letters. It's okay to call
your parameters "prompt" instead of "prmt". Remember, that's part of
your API.

I'd whitewash the bikeshed a slightly different colour, personally.

_SENTINEL = object()
def get_number(prompt, *, min=None, max=None, default=_SENTINEL, type=int):

Broadly the same as you have (modulo variable names), but there's no
need for the boolean 'abrt', since setting default to None will have
the same effect - hence the dedicated sentinel object to represent "no
default". (I also mandated keyword args, since that's how you're using
them anyway.) The one real change I'd make is to replace the boolean
flag "flt" with a type, so you now say:

x = get_number("Number (enter to terminate):  ", type=float)

It reads more cleanly than "flt=True", and you don't have to look up
any docs to grok it; plus, if you ever need to, you can use
"type=Decimal" or something. It's simpler inside the code too - "num =
type(val)". If you don't like shadowing the built-in name 'type', feel
free to call this something else, but IMO it's okay to shadow here.

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


Re: The "loop and a half"

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 09:08 am, Stefan Ram wrote:

> Steve D'Aprano  writes:
>>On Wed, 4 Oct 2017 04:45 am, Rhodri James wrote:
>>>On 03/10/17 18:29, Stefan Ram wrote:
Is this the best way to write a "loop and a half" in Python?
>>>Define "best".
>>I'd start with "define loop and a half".

[...]
>   I might got Sahami wrong, but it took it to mean this kind
>   of loop (in pseudo code, which is not necessarily Python):
> 
> while condition
>...
>...
>...
>if condition
>   ...
>end if
> end while
> 
>   The two »condition«s above are the same condition.

Hmmm. To me, that appears to be just one case of an unlimited number of
different possibilities, none more special or general than any of the others:

while condition
   ...
   if condition
  ...
   else
  ...
   end if
   ...
   if condition
  ...
   else
  ...
   end if
   ...
   if not condition
  ...
   end if
   ...
   ...
   # etc
end while


I don't see why your version is any more special, or deserving of a name, than
any other variety:

while condition
   ...
   while condition
  ...
   end while
   ...
   if not condition
   ...
   end if
   while not condition
   ...
   if not condition
   ...
   else
   ...
   end if
   ...
   end while
   ...
   while condition
   ...
   end while
   ...
end while


There is literally an infinite number of possibilities for what can go inside
a while loop. More while loops, if...else, for loops, any structure you like.
What is so special about "if condition..." that it deserves a special name or
syntax?


>   Initially, one loops through this loop an integral
>   number of times.
> 
>   But eventually the conditions is made false by the
>   upper half of the loop, so then the lower half is
>   skipped. 

Or the middle third is skipped.

Of the second and third parts of five.

Or the fifth, eighth and eleventh parts of twelve.


>   But at this point in the class, I only have 
>   shown »while« and »if« so far, iterators and for-loops
>   will only be introduced later.

Why?

Teaching while loops before for-each loops is backwards. That's one of the
bigger problems with "Learn Python the Hard Way", and I see people struggle,
really really struggle, so solve problems using a while loop which are
*trivial* using a for loop.

For-each loops are MUCH easier to understand, and should be taught first.

"Do something to each of these items" is a very natural, almost instinctive
operation. While loops are harder to write correctly, harder to reason about,
and harder to learn.

Just because for-each loops are, in some sense, derived from while loops,
doesn't mean you should teach them first.


-- 
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: optional int- and float arguments

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 12:17 pm, Stefan Ram wrote:

> |>>> str(object='abc')
> |'abc'

That's probably also a bug.



-- 
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: The "loop and a half"

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote:

> You know, you don't HAVE to economize on letters. It's okay to call
> your parameters "prompt" instead of "prmt". Remember, that's part of
> your API.


Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of vwel wth
nt nuff 4 vrybdy.



-- 
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: The "loop and a half"

2017-10-03 Thread Chris Angelico
On Wed, Oct 4, 2017 at 2:48 PM, Steve D'Aprano
 wrote:
> On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote:
>
>> You know, you don't HAVE to economize on letters. It's okay to call
>> your parameters "prompt" instead of "prmt". Remember, that's part of
>> your API.
>
>
> Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of vwel wth
> nt nuff 4 vrybdy.
>

And then English will turn into an abjad like Arabic. Yes, I see how
it is. Python is a sneaky plan by Islamic extremists to make us use up
all our vowels.

(I'd end the post there, except that I've learned from past experience
that there is no statement so ridiculous that people will know for
sure that you're joking. So for the humour-impaired: THIS POST WAS A
JOKE. Okay? Good.)

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


Re: on a very slow function

2017-10-03 Thread Steve D'Aprano
On Tue, 3 Oct 2017 04:23 am, Ian Kelly wrote:

>> py> (2**75 + 7) % 12  # Expected value.
>> 3
>> py> ((2**75) % 12 + (7 % 12)) % 12  # Correct.
>> 3
>> py> (2**75) % 12 + (7 % 12)  # Incorrect.
>> 15
> 
> No, only the final one is necessary. Modding the result of the
> exponentiation might be useful for performance, but if c is expected
> to be small then it may be pointless to mod that as well.
>
> py> ((2**75) % 12 + 7) % 12  # Still correct.
> 3

Its been years since I've had to tackle modulo arithmetic, but the more I
think about it, the more I think you are right.



-- 
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: newb question about @property

2017-10-03 Thread Steve D'Aprano
On Wed, 4 Oct 2017 02:00 am, bartc wrote:

> Does all this advanced stuff (which I don't understand and which doesn't
> look very appealing either; hopefully I will never come across such
> code) still count as programming?

I could not have hoped to see a more perfect example of the Blub effect in
action if I had invented it myself.


As long as our hypothetical Blub programmer is looking 
down the power continuum, he knows he's looking down.
Languages less powerful than Blub are obviously less
powerful, because they're missing some feature he's used
to. But when our hypothetical Blub programmer looks in
the other direction, up the power continuum, he doesn't
realize he's looking up. What he sees are merely weird
languages. He probably considers them about equivalent
in power to Blub, but with all this other hairy stuff
thrown in as well. Blub is good enough for him, because
he thinks in Blub.


http://www.paulgraham.com/avg.html


> It seems to me the equivalent of an advanced driving course teaching you
> how to customise your car rather than involving any actual driving.

You don't think that adding a cache for an expensive function is programming?

If you had ten expensive functions, and you wanted to add a cache to each of
them, would you write out ten separate caches (probably copying and pasting
the code each time)?

Or would you write a function that builds a cache and adds it to the expensive
function *once*, then call it ten times, once for each function being
wrapped?

My examples didn't include a full-blown cache, just the beginnings of one, but
the principle still stands. Program smart, not hard: don't do things by hand
if you can write a function to do them.

That you think that this is not programming is an indictment off your
programming skills. These sorts of functional programming techniques go back
to the 1950s, Lisp is literally the second oldest high-level language ever
(only Fortran is older). You may or may not have been a hotshot in your
little corner of the programming world, but there's an entire world out
there.



-- 
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