Re: Distributing multiple packages with on setup.py

2017-09-29 Thread dieter
Jimmy Thrasibule  writes:
> ...
> Is it possible, still keeping one unique ``setup.py`` file, to create
> 3 independent packages?
>
> * ``myproj.common``
> * ``myproj.subpackage1``
> * ``myproj.subpackage2``
>
> Also I'd like to specify that when installing ``myproj.subpackage1``,
> ``myproj.common`` is required or that ``myproj.subpackage2`` will
> require both ``myproj.common`` and ``myproj.subpackage1``.

Yes - in principal - but ...
the "setup.py" essentially contains the "setup" function call
and this call needs package specific parameter values (e.g.
the package name, the package dependencies, ...).
If you want a single "setup.py", this "setup.py" must use
some (potentially sophisticated) logic to determine those
package specific parameters and select (depending on the context)
which parameter set to pass on to the "setup" function call.

Personally, I never want interested in this approach.

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


Re: Solution Manual Test Bank for Financial and Managerial Accounting for MBAs 5th Edition by Easton

2017-09-29 Thread abusayem12143
On Thursday, June 29, 2017 at 6:04:07 AM UTC-4, Test Banks wrote:
> Greetings Students, 
> 
> We do have Solution Manuals and Test Bank for FINANCIAL AND MANAGERIAL 
> ACCOUNTING FOR MBAs 5TH EDITION BY EASTON at reasonable price. You can get 
> above mentioned resources by sending email to pro.fast(@)hotmail(dot)com 
> 
> Send your order queries at PRO.FAST(@)HOTMAIL(DOT)COM 
> 
> Below are details given for this book 
> 
> Book Name: FINANCIAL AND MANAGERIAL ACCOUNTING FOR MBAs 
> Authors: Peter D. Easton, Robert F. Halsey, Mary Lea McAnally, Al L. 
> Hartgraves, Wayne J. Morse 
> Edition: 5th E 
> ISBN-10: 1618532324 
> ISBN-13: 9781618532329 
> Product Format: MS Word 
> Total Modules: 25 
> 
> Please mention complete details for your book so we could send you sample 
> accordingly. 
> 
> Best Regards, 
> 
> P.S : Please do not post your reply here. We do not monitor queries here. 
> Simply send us an email directly to PRO.FAST (@) HOTMAIL (DOT) COM

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


Distributing multiple packages with on setup.py

2017-09-29 Thread Jimmy Thrasibule
Hi,

I've reorganized my Python project to be under a same name umbrella.
My project can now be seen as multiple subsystems than can depend on
each other. That means that every sub-package can now be distributed
alone so that only required dependencies can be installed.

The old structure:


/
├─ myproj/
│  ├─ __init__.py
│  ├─ mod1.py
│  ├─ subpackage1/
│  └─ subpackage2/
└─ setup.py


The new structure:


/
├─ myproj/
│  ├─ common/
│  │  └─ mod1.py
│  ├─ subpackage1/
│  ├─ subpackage2/
│  └─ __init__.py
└─ setup.py


As you can see not much has changed except that `myproj` is now a
`namespace package
`_
and that sub-packages ``common``, ``subpackage1`` and ``subpackage2``
can now be distributed independently.

Is it possible, still keeping one unique ``setup.py`` file, to create
3 independent packages?

* ``myproj.common``
* ``myproj.subpackage1``
* ``myproj.subpackage2``

Also I'd like to specify that when installing ``myproj.subpackage1``,
``myproj.common`` is required or that ``myproj.subpackage2`` will
require both ``myproj.common`` and ``myproj.subpackage1``.

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


The mysterious ways of Python mailing list

2017-09-29 Thread Vincent Vande Vyvre
Is it a reason why my messages appears always a long time (today 9 
hours) on the list after I send it ?


Send at 19:14 UTC+2


Vincent

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread justin walters
On Fri, Sep 29, 2017 at 12:14 PM, Bill  wrote:

>
> I'll write for the possible benefit of any beginners who may be reading.
> I guess by definition, if one still has a "bug" it's because one doesn't
> quite understand what the code is doing. And I would say you should lose
> your license if you "fix something", and don't understand why it works
> (within reason of course--some mystery's of library functions should
> probably remain so forever). So ADT (Any Damn Thing--I just made that up
> that acronym) you can do to understand your code better is fair game! : )
>   In fact, in my experience, the sooner you start getting a little bit
> angry, the sooner you'll get to the heart of matter.  Usually, what looks
> like a long route, isn't, in the end.  Don't be afraid to write *really
> descriptive* output statements, and do so even though you "don't need to".
> Besides for making you more productive, it will help soothe you : )
>  Beginners almost never need to...  I think that getting out of the
> beginner phase requires developing a certain amount of humility.  Just wait
> 5 or 10 years, any look back, and see if what I've written isn't more true
> than false.
>
> The only part I am unsure of is whether you are supposed to get a little
> big angry or not (YMMV).  I find 2 cups of coffee about right. That is, 2
> before and 2 after lunch. Of course, that does not include "meetings".
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Reminds me of a bug I had to chase down recently.

I've been working on the front-end of this web application for a while.
It's an SPA built
with Vuejs. The bug arose in the login workflow. Basically, it went like
this:

client loads login screen -> user enters credentials into form and submits
-> client sends credentials to server ->
server verifies credentials -> server sends back auth token -> client
receives auth token and stores it ->
client redirects user to home screen -> home screen makes get request for
some data

Now, this worked perfectly fine everywhere except for Safari 9.1 on OSX.

A user could login just fine on Safari 9.1, but after that, no requests
would complete. Safari's dev tools
were no help because they were not showing any errors or any failed
requests. I checked the server logs
and found that no requests were even sent.

It took me 2 days to figure out this bug. I tracked it down to the function
that injected the authorization
header into all requests if the user was logged in. Based on
troubleshooting, I knew it couldn't be anything else.
That said, I was still confused because this worked on literally every
other browser(even IE 9).

After searching for people with similar problems and coming up with nothing
I got to thinking about the
asynchronous nature of JS. So, out of sheer frustration I moved the line of
code that stored the auth token
from one function to another, booted up my testing environment, and it
worked.

So, the bug was basically because Safari was waiting for a specific
function call to complete before
it committed the token to local storage even though the line of code that
did so was within said function.

So, two days worth of work to move a single line of code from one function
to another. You can only imagine
the tirade of curse words directed at apple during the above calamity.

Had I simply written a console log for every function down the chain, I may
have been able to find the
cause of the bug more quickly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Gregory Ewing

Bill wrote:
Don't be afraid to write *really descriptive* output statements, and do 
so even though you "don't need to".


Yeah, often when I'm writing something tricky I'll proactively
put in some code to print intermediate state to reassure myself
that things are on track. Being more verbose with them than I
think necessary can save a few trips around the debug cycle.

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Gregory Ewing

Steve D'Aprano wrote:

(1) I know there's a bug in a specific chunk of code, but I'm having trouble
working out where. When everything else fails, if I perturb the code a bit
(reorder lines, calculate things in a different order, rename variables, etc)
it may change the nature of the bug enough for me to understand what's
happening.


> Its an experiment, but not really "carefully designed".

I think it's more carefully designed than you give it credit for.
You still need to understand quite a lot about the program to know
what changes are likely to yield useful information, and how to
interpret the results.


Its more like "what
happens if we hit this bit with a hammer?"


In biology it's called a "shotgun experiment". "If we blast this
bit of DNA with radiation, what part of the organism does it
mess up?"


(2) I hate off by one errors, and similar finicky errors that mean your code is
*almost* right. I especially hate them when I'm not sure which direction I'm
off by one. If you have unit tests that are failing, sometimes its quicker and
easier to randomly perturb the specific piece of code until you get the right
answer, rather than trying to analyse it.


With off-by-one errors it's still pretty specific -- start
the loop at 1 instead of 0, etc.

But in cases like that I prefer to rewrite the code so that
it's obvious where it should start and finish.


The complexity of code increases faster than our ability to manage that
complexity.


And then there's "If you write the code as cleverly as you can,
you won't be smart enough to debug it!"

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


Re: Redirecting stdio streams with a context manager

2017-09-29 Thread Thomas Jollans
On 29/09/17 19:06, Steve D'Aprano wrote:
> In the standard library's contextlib.py module, there is a class for 
> redirecting
> standard I/O streams, and two public functions. The code is short enough to
> reproduce here:
>
> # From Python 3.5
>
> class _RedirectStream:
> _stream = None
> def __init__(self, new_target):
> self._new_target = new_target
> # We use a list of old targets to make this CM re-entrant
> self._old_targets = []
> def __enter__(self):
> self._old_targets.append(getattr(sys, self._stream))
> setattr(sys, self._stream, self._new_target)
> return self._new_target
> def __exit__(self, exctype, excinst, exctb):
> setattr(sys, self._stream, self._old_targets.pop())
>
> class redirect_stdout(_RedirectStream):
> # docstring removed
> _stream = "stdout"
>
> class redirect_stderr(_RedirectStream):
> # docstring removed
> _stream = "stderr"
>
>
>
> I don't understand the comment "We use a list of old targets to make this CM
> re-entrant". Under what circumstances will there ever be more than a single
> entry in _old_targets?
This makes every *instance* re-entrant.
I don't really see the point, but I think this would be a contrived
example of such circumstances:

redir_file1 = redirect_stdout(f1)
redir_file2 = redirect_stdout(f2)

with redir_file1:
# do stuff
with redir_file2:
# Other stuff
# Oh no wait actually
with redir_file1:
# Dum dee dum dee dum
pass


>
> If you use the context manager twice:
>
> with redirect_stdout(f1) as instance1:
> with redirect_stdout(f2) as instance2:
> pass
>
> the two calls will return different instances and sys.stdout will be set as
> follows:
>
> # before first call to redirect_stdout
> sys.stdout = __stdout__  # the original setting
>
> # first call __enter__
> save __stdout__ in instance1._old_targets
> set sys.stdout = f1
>
> # second call __enter__
> save f1 in instance2._old_targets
> set sys.stdout = f2
>
> # second call __exit__
> restore sys.stdout = f1
>
> # first call __exit__
> restore sys.stdout = __stdout__
>
>
> I'm not seeing why _old_targets is a list.
>
>
> Can anyone explain?
>
>

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Chris Angelico
On Sat, Sep 30, 2017 at 5:14 AM, Bill  wrote:
> I'll write for the possible benefit of any beginners who may be reading.  I
> guess by definition, if one still has a "bug" it's because one doesn't quite
> understand what the code is doing. And I would say you should lose your
> license if you "fix something", and don't understand why it works (within
> reason of course--some mystery's of library functions should probably remain
> so forever).

My programmer's license comes from MIT and it can't be lost.

https://opensource.org/licenses/MIT

Kappa

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Bill

Chris Angelico wrote:

On Sat, Sep 30, 2017 at 2:42 AM, Steve D'Aprano
 wrote:

Oh, and I'd like to make a (moderate) defense of a kind of "bug fixing by random
perturbation". Obviously making unrelated, arbitrary changes to code is bad.
But making non-arbitrary but not fully understood changes to relevant code
sections can be useful in (at least) two scenarios.

(1) I know there's a bug in a specific chunk of code, but I'm having trouble
working out where. When everything else fails, if I perturb the code a bit
(reorder lines, calculate things in a different order, rename variables, etc)
it may change the nature of the bug enough for me to understand what's
happening.

That's not *random* or *arbitrary* changes, but they are changes not directed at
any specific outcome other than "make the code a bit different, and see if the
error changes". I'd like to say it is the debugging technique of last resort,
except its perhaps not quite as *last* resort as I'd like, especially in code
I'm not familiar with.

Its an experiment, but not really "carefully designed".


I'll write for the possible benefit of any beginners who may be 
reading.  I guess by definition, if one still has a "bug" it's because 
one doesn't quite understand what the code is doing. And I would say you 
should lose your license if you "fix something", and don't understand 
why it works (within reason of course--some mystery's of library 
functions should probably remain so forever). So ADT (Any Damn Thing--I 
just made that up that acronym) you can do to understand your code 
better is fair game! : )In fact, in my experience, the sooner you 
start getting a little bit angry, the sooner you'll get to the heart of 
matter.  Usually, what looks like a long route, isn't, in the end.  
Don't be afraid to write *really descriptive* output statements, and do 
so even though you "don't need to". Besides for making you more 
productive, it will help soothe you : )   Beginners almost never need 
to...  I think that getting out of the beginner phase requires 
developing a certain amount of humility.  Just wait 5 or 10 years, any 
look back, and see if what I've written isn't more true than false.


The only part I am unsure of is whether you are supposed to get a little 
big angry or not (YMMV).  I find 2 cups of coffee about right. That is, 
2 before and 2 after lunch. Of course, that does not include "meetings".

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


Re: Redirecting stdio streams with a context manager

2017-09-29 Thread Peter Otten
Steve D'Aprano wrote:

> In the standard library's contextlib.py module, there is a class for
> redirecting standard I/O streams, and two public functions. The code is
> short enough to reproduce here:
> 
> # From Python 3.5
> 
> class _RedirectStream:
> _stream = None
> def __init__(self, new_target):
> self._new_target = new_target
> # We use a list of old targets to make this CM re-entrant
> self._old_targets = []
> def __enter__(self):
> self._old_targets.append(getattr(sys, self._stream))
> setattr(sys, self._stream, self._new_target)
> return self._new_target
> def __exit__(self, exctype, excinst, exctb):
> setattr(sys, self._stream, self._old_targets.pop())
> 
> class redirect_stdout(_RedirectStream):
> # docstring removed
> _stream = "stdout"
> 
> class redirect_stderr(_RedirectStream):
> # docstring removed
> _stream = "stderr"
> 
> 
> 
> I don't understand the comment "We use a list of old targets to make this
> CM re-entrant". Under what circumstances will there ever be more than a
> single entry in _old_targets?
> 
> If you use the context manager twice:
> 
> with redirect_stdout(f1) as instance1:
> with redirect_stdout(f2) as instance2:
> pass

That's the sane approach, but I just learned that you can reuse a single 
instance:

>>> here = io.StringIO()
>>> there = io.StringIO()
>>> h = redirect_stdout(here)
>>> t = redirect_stdout(there)
>>> with h:
... print("ham")
... with t:
... print("foo")
... with h:
... print("spam")
... with t:
... print("bar")
... 
>>> here.getvalue()
'ham\nspam\n'
>>> there.getvalue()
'foo\nbar\n'


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


Re: Line terminators in Python?

2017-09-29 Thread Rob Gaddi

On 09/29/2017 10:54 AM, Stefan Ram wrote:

   In some languages, printing »'\n'«, the Unicode code point 10,
   will have the effect of printing a line terminator, which might
   mean that the output device actually receives »\r\n«.

   The line terminator ostensibly depends on the operating
   system, but actually it depends on the output system. E.g.,
   under one operating system the console might accept another
   set of line separators than an editor. (Under Windows,
   »wordpad« accepts »\n«, while »notepad« requires »\r\n«.)

   What is the recommended way to terminate a line written with
   Python? Is it »\n« or something else? For example, in Java,
   in some cases, one should terminate the line with the value
   of »java.lang.System.lineSeparator()« which might or might
   not be equal to the value of »"\n"«.

   Does it possibly depend on the entity being written to, which
   might be

   - the Python console,
   - the IDLE console,
   - the operating system console or
   - a text file?



As everyone else has said; for general purpose (any of your cases) use 
you should always just use '\n' and it automagically works.  The only 
time I've ever needed to explicitly worry about '\r' is communicating 
over sockets or serial ports to devices.  And in those cases you need to 
stuff them with bytes rather than str anyhow, so you're already down in 
the gory bits.


--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Line terminators in Python?

2017-09-29 Thread Chris Warrick
On 29 September 2017 at 19:54, Stefan Ram  wrote:
>   In some languages, printing »'\n'«, the Unicode code point 10,
>   will have the effect of printing a line terminator, which might
>   mean that the output device actually receives »\r\n«.
>
>   The line terminator ostensibly depends on the operating
>   system, but actually it depends on the output system. E.g.,
>   under one operating system the console might accept another
>   set of line separators than an editor. (Under Windows,
>   »wordpad« accepts »\n«, while »notepad« requires »\r\n«.)
>
>   What is the recommended way to terminate a line written with
>   Python? Is it »\n« or something else? For example, in Java,
>   in some cases, one should terminate the line with the value
>   of »java.lang.System.lineSeparator()« which might or might
>   not be equal to the value of »"\n"«.
>
>   Does it possibly depend on the entity being written to, which
>   might be
>
>   - the Python console,
>   - the IDLE console,
>   - the operating system console or
>   - a text file?

It depends on the mode used to open the output file.
https://docs.python.org/3/library/functions.html#open

sys.stdout is opened in 'w' mode by default (writing, text mode). Text
mode means that non-Unix newlines (\r\n, \r) are translated to '\n'
when reading, and '\n' is translated to the system local newline when
writing. So, if you’re working in text mode (which also handles
encodings and returns Unicode strings on Python 3), you can just
assume '\n'.

If you’re curious what the local newline is, look at os.linesep:
https://docs.python.org/3/library/os.html#os.linesep

-- 
Chris Warrick 
PGP: 5EAAEA16
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Line terminators in Python?

2017-09-29 Thread Chris Angelico
On Sat, Sep 30, 2017 at 3:54 AM, Stefan Ram  wrote:
>   In some languages, printing »'\n'«, the Unicode code point 10,
>   will have the effect of printing a line terminator, which might
>   mean that the output device actually receives »\r\n«.
>
>   The line terminator ostensibly depends on the operating
>   system, but actually it depends on the output system. E.g.,
>   under one operating system the console might accept another
>   set of line separators than an editor. (Under Windows,
>   »wordpad« accepts »\n«, while »notepad« requires »\r\n«.)
>
>   What is the recommended way to terminate a line written with
>   Python? Is it »\n« or something else? For example, in Java,
>   in some cases, one should terminate the line with the value
>   of »java.lang.System.lineSeparator()« which might or might
>   not be equal to the value of »"\n"«.
>
>   Does it possibly depend on the entity being written to, which
>   might be
>
>   - the Python console,
>   - the IDLE console,
>   - the operating system console or
>   - a text file?
>

Always use "\n". In the event that you actually need "\r\n", transform
that on output. In effect, you can treat "Windows-style newlines" vs
"POSIX-style newlines" as a form of text encoding, to be dealt with at
boundary locations only; when you read a file, you clean up the
newlines, and when you write, you *might* transform them. Notepad
sucks, so don't do things just for its sake; but certain network
protocols stipulate carriage return/line feed as their end-of-line.
HTTP, for instance, is clearly specified as such in RFC 2616 [1] -
section 19.3 recommends that "\n" be accepted for the sake of
interoperability, but the official line ending is CR LF. So if you're
writing to a socket, you might do a two-step process of transforming
newlines and also encoding UTF-8, but inside the application, keep
everything as Unicode text with "\n" between lines.

ChrisA

[1] https://www.ietf.org/rfc/rfc2616.txt
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Line terminators in Python?

2017-09-29 Thread Thomas Jollans
On 29/09/17 19:54, Stefan Ram wrote:
>   In some languages, printing »'\n'«, the Unicode code point 10,
>   will have the effect of printing a line terminator, which might
>   mean that the output device actually receives »\r\n«.
>
>   The line terminator ostensibly depends on the operating
>   system, but actually it depends on the output system. E.g.,
>   under one operating system the console might accept another
>   set of line separators than an editor. (Under Windows,
>   »wordpad« accepts »\n«, while »notepad« requires »\r\n«.)
>
>   What is the recommended way to terminate a line written with
>   Python? Is it »\n« or something else? For example, in Java,
>   in some cases, one should terminate the line with the value
>   of »java.lang.System.lineSeparator()« which might or might
>   not be equal to the value of »"\n"«.
>
>   Does it possibly depend on the entity being written to, which
>   might be
>
>   - the Python console,
>   - the IDLE console,
>   - the operating system console or
>   - a text file?
>
Use \n.

For text I/O, Python translates \n to \r\n on Windows. For binary I/O,
it doesn't. (This means that it's important to specify text or binary
mode in your calls to open() if you want your code to be portable).

\r\n is not translated to \n on Unix. So, if you want your code to do
the right thing, use \n.

-- Thomas

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


Re: Spacing conventions

2017-09-29 Thread Chris Angelico
On Sat, Sep 30, 2017 at 3:46 AM, Steve D'Aprano
 wrote:
> On Fri, 29 Sep 2017 03:01 pm, Chris Angelico wrote:
>
>> On Fri, Sep 29, 2017 at 2:38 PM, Steve D'Aprano
>>  wrote:
>>> On Thu, 28 Sep 2017 03:56 pm, Bill wrote:
>>>
 I worked in maintenance programming.  You got the hand you were dealt!
 And you weren't allowed to "improve" the code unless the customer
 contracted you to do so.
>>>
>>> How do you tell the difference between a bug fix and an code improvement, if
>>> the behaviour of the program remains the same?
>>
>> If the behaviour remains *exactly* the same, then it's a code
>> improvement (aka a refactoring), not a bug fix. Or, looking at it
>> another way: if there is absolutely no change to behaviour, how could
>> you tell that there was a bug in it?
>
> Well obviously you fix the bug, not just refactor and keep the bug. Sorry if
> that wasn't clear enough.
>
>
>> And yes, trying to convince a customer that it's worth paying for
>> improvements that don't change anything visible is hard.
>
> The point of refactoring is to make it easy to fix the bug:
>
> "Two hours refactoring, plus thirty seconds to fix the bug; versus 18 hours to
> fix the bug without refactoring."
>
> Plus or minus six weeks on each of those times *tongue pressed firmly in 
> cheek*
>
>
> But more seriously, I'm not suggesting you refactor the whole code base. You
> only refactor the bit you are touching *right now*.

This is the easy one. You're touching this code, you improve it. That
applies to most things - style issues, local variable names, whatever.
You don't make sweeping changes, but when you're messing with things
anyway, you can clean things up.

> Don't even mention refactoring. That sounds like an improvement, and they said
> they don't want improvements.
>
> But even the most unreasonable client will surely understand that before you 
> can
> fix the bug, you have to find it, and that requires understanding the code.
> Cleaning up the *immediately relevant section of code* (giving variables
> meaningful names, extracting common functionality, etc) is part of the
> necessary process of understanding the code and finding the cause of the bug 
> in
> the shortest possible time, and the fact that you end up with cleaner code and
> less technical debt at the end is a happy accident. That's not why you did it,
> so technically all you did was fix the bug, exactly as told.
>
> (They didn't tell you *how* to fix the bug. If they knew how, they wouldn't 
> need
> you.)

The trouble is that sometimes the refactoring doesn't pay for itself
with today's bug, but it might with tomorrow's bugs. Do you spend two
hours refactoring and bugfixing, or one hour just fixing the bug and
coping with the mess?

> But I bet that for *most*
> customers, if you give them the choice between:
>
> (1) Minimize the number of lines of code changed; or
>
> (2) Minimize the number of dollars on the invoice
>
> they'll usually prefer (2).

The improvement won't minimize the number of dollars on *this*
invoice. Can you sell them a line item of "future bug fixes will take
less time"? You can't put an actual figure on it ("will save 0.5 hours
per fortnight for the next year"), but you know the benefit is real.
That's why it's hard to sell the refactor.

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


Re: Spacing conventions

2017-09-29 Thread Steve D'Aprano
On Fri, 29 Sep 2017 03:01 pm, Chris Angelico wrote:

> On Fri, Sep 29, 2017 at 2:38 PM, Steve D'Aprano
>  wrote:
>> On Thu, 28 Sep 2017 03:56 pm, Bill wrote:
>>
>>> I worked in maintenance programming.  You got the hand you were dealt!
>>> And you weren't allowed to "improve" the code unless the customer
>>> contracted you to do so.
>>
>> How do you tell the difference between a bug fix and an code improvement, if
>> the behaviour of the program remains the same?
> 
> If the behaviour remains *exactly* the same, then it's a code
> improvement (aka a refactoring), not a bug fix. Or, looking at it
> another way: if there is absolutely no change to behaviour, how could
> you tell that there was a bug in it?

Well obviously you fix the bug, not just refactor and keep the bug. Sorry if
that wasn't clear enough.


> And yes, trying to convince a customer that it's worth paying for
> improvements that don't change anything visible is hard.

The point of refactoring is to make it easy to fix the bug:

"Two hours refactoring, plus thirty seconds to fix the bug; versus 18 hours to
fix the bug without refactoring."

Plus or minus six weeks on each of those times *tongue pressed firmly in cheek*


But more seriously, I'm not suggesting you refactor the whole code base. You
only refactor the bit you are touching *right now*. That's especially relevant
for Bill's comment about loops which are hundreds of lines long. There's a bug
somewhere in the loop, and finding the bug is going to take many hours. So
spend half that time cleaning the loop up by factoring bits of it out (if
possible!) in order to (1) understand what the loop does, and (2) simplify the
debugging process.

Technically its an improvement. But its not a *functional* improvement, which is
what people usually mean when they say no improvements, only bug fixes. It is a
code-quality improvement[1] *necessary to fix the bug*.

Perhaps not strictly necessary. You could spend five times as long fixing the
bug (and introducing two new ones) by *not* refactoring.

Of course, I understand that sometimes there are political reasons why you can't
do that, and they're not always bad reasons.  But I bet that for *most*
customers, if you give them the choice between:

(1) Minimize the number of lines of code changed; or

(2) Minimize the number of dollars on the invoice

they'll usually prefer (2).

Don't try to sell them on code refactoring as an investment for the future,
they're not interested.

Don't try to convince them that they need to reduce technical debt. Debt is
something for the next generation to worry about[2].

Don't even mention refactoring. That sounds like an improvement, and they said
they don't want improvements.

But even the most unreasonable client will surely understand that before you can
fix the bug, you have to find it, and that requires understanding the code.
Cleaning up the *immediately relevant section of code* (giving variables
meaningful names, extracting common functionality, etc) is part of the
necessary process of understanding the code and finding the cause of the bug in
the shortest possible time, and the fact that you end up with cleaner code and
less technical debt at the end is a happy accident. That's not why you did it,
so technically all you did was fix the bug, exactly as told.

(They didn't tell you *how* to fix the bug. If they knew how, they wouldn't need
you.)

But, as always, this is risky if you don't have a good test suite.



> Which is why 
> a lot of companies end up merely paying interest on their technical
> debt, and never paying off any of the capital.
> 
> ChrisA


[1] Maybe. The downside of piecemeal refactoring is that sometimes it increases
complexity until you pass a critical point and it starts decreasing it again.

[2] And that's not always a bad thing. Debt is not always bad: its money that
you can invest in building your infrastructure or startup or keeping a roof
over your head until you find a job, and it makes sense to delay paying off the
debt until you have a better income stream that will afford it more easily.



-- 
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: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Chris Angelico
On Sat, Sep 30, 2017 at 2:42 AM, Steve D'Aprano
 wrote:
> Oh, and I'd like to make a (moderate) defense of a kind of "bug fixing by 
> random
> perturbation". Obviously making unrelated, arbitrary changes to code is bad.
> But making non-arbitrary but not fully understood changes to relevant code
> sections can be useful in (at least) two scenarios.
>
> (1) I know there's a bug in a specific chunk of code, but I'm having trouble
> working out where. When everything else fails, if I perturb the code a bit
> (reorder lines, calculate things in a different order, rename variables, etc)
> it may change the nature of the bug enough for me to understand what's
> happening.
>
> That's not *random* or *arbitrary* changes, but they are changes not directed 
> at
> any specific outcome other than "make the code a bit different, and see if the
> error changes". I'd like to say it is the debugging technique of last resort,
> except its perhaps not quite as *last* resort as I'd like, especially in code
> I'm not familiar with.
>
> Its an experiment, but not really "carefully designed". Its more like "what
> happens if we hit this bit with a hammer?" except that programmers, unlike
> engineers, have the luxury of an Undo switch :-)

Sometimes, when I'm debugging something with one of my students, I'll
say something like "Let's do something stupid". That prefaces a
suggested change that is, perhaps:
* logging something that, by all sane logic, cannot possibly be wrong;
* altering the form of a piece of code in a way that shouldn't affect anything;
* changing something that logically should break the code worse, not fix it;
* or worse.

They're still not "random" changes, but when you exhaust all the
logical and sane things to try, sometimes you do something stupid and
it reveals the bug. I wouldn't EVER tell someone to assume that
they've hit a language or library bug - but if you make a meaningless
change and now it works, maybe that's what you've hit. It does happen.

"Why does my program crash when it talks to THIS server, but it's fine
talking to THAT server?"

... half an hour of debugging later ...

"Okay, so THIS server supports elliptic curve cryptography, but THAT
one doesn't. Great. That still doesn't explain the crash."

... two hours of debugging later ...

"Huh. Maybe this library has a bug with ECC?"

That's pretty close to what happened to me today, with the exception
that I spent less time on it (because I had the library's source code
handy). But in any case, it's a good reason to occasionally try
something stupid.

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


Redirecting stdio streams with a context manager

2017-09-29 Thread Steve D'Aprano
In the standard library's contextlib.py module, there is a class for redirecting
standard I/O streams, and two public functions. The code is short enough to
reproduce here:

# From Python 3.5

class _RedirectStream:
_stream = None
def __init__(self, new_target):
self._new_target = new_target
# We use a list of old targets to make this CM re-entrant
self._old_targets = []
def __enter__(self):
self._old_targets.append(getattr(sys, self._stream))
setattr(sys, self._stream, self._new_target)
return self._new_target
def __exit__(self, exctype, excinst, exctb):
setattr(sys, self._stream, self._old_targets.pop())

class redirect_stdout(_RedirectStream):
# docstring removed
_stream = "stdout"

class redirect_stderr(_RedirectStream):
# docstring removed
_stream = "stderr"



I don't understand the comment "We use a list of old targets to make this CM
re-entrant". Under what circumstances will there ever be more than a single
entry in _old_targets?

If you use the context manager twice:

with redirect_stdout(f1) as instance1:
with redirect_stdout(f2) as instance2:
pass

the two calls will return different instances and sys.stdout will be set as
follows:

# before first call to redirect_stdout
sys.stdout = __stdout__  # the original setting

# first call __enter__
save __stdout__ in instance1._old_targets
set sys.stdout = f1

# second call __enter__
save f1 in instance2._old_targets
set sys.stdout = f2

# second call __exit__
restore sys.stdout = f1

# first call __exit__
restore sys.stdout = __stdout__


I'm not seeing why _old_targets is a list.


Can anyone explain?


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

2017-09-29 Thread Bill

Stefan Ram wrote:


   The customer pays for the solution. The software
   manufacturer does the refactoring for it's own sake,
   because when it's a longer running project, the
   refactorings will pay for themself.



The customer owns the source code (at least where I was).  YMMV
--
https://mail.python.org/mailman/listinfo/python-list


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Steve D'Aprano
On Fri, 29 Sep 2017 08:34 pm, D'Arcy Cain wrote:

> On 09/29/2017 03:15 AM, Steve D'Aprano wrote:
>> "Carefully-designed experiments" -- yeah, that is so totally how the coders
>> I've worked with operate *wink*
>> 
>> I think that's an awfully optimistic description of how the average
>> programmer works :-)
> 
> Better not hire average programmers then.

Okay.

Can I consider the top 10% of programmers, or must I only consider only those in
the top 1%?

If I'm on a budget and the code isn't that critical, can I consider those in the
top 20% for junior roles?


> I do "Carefully-designed 
> experiments" to find non-obvious bugs so I guess I am not average.

Okay.

By the way, *in context* (before you deleted the original text) there was no
mention about "non-obvious bugs". Greg Ewing and Chris Angelico were talking
about the general difference between the process used by novices and that used
by experts and how beginners often attempt to fix bugs by making random
changes, while experts don't.

I've certainly seen beginners make arbitrary changes to unrelated parts of their
code trying to fix a bug. Often many different changes all at once. So that's
another difference between beginners and experts:

- experts have the self-control to make only one change at a time, 
  when it matters; beginners don't know when it matters.


Oh, and I'd like to make a (moderate) defense of a kind of "bug fixing by random
perturbation". Obviously making unrelated, arbitrary changes to code is bad.
But making non-arbitrary but not fully understood changes to relevant code
sections can be useful in (at least) two scenarios.

(1) I know there's a bug in a specific chunk of code, but I'm having trouble
working out where. When everything else fails, if I perturb the code a bit
(reorder lines, calculate things in a different order, rename variables, etc)
it may change the nature of the bug enough for me to understand what's
happening.

That's not *random* or *arbitrary* changes, but they are changes not directed at
any specific outcome other than "make the code a bit different, and see if the
error changes". I'd like to say it is the debugging technique of last resort,
except its perhaps not quite as *last* resort as I'd like, especially in code
I'm not familiar with.

Its an experiment, but not really "carefully designed". Its more like "what
happens if we hit this bit with a hammer?" except that programmers, unlike
engineers, have the luxury of an Undo switch :-)


(2) I hate off by one errors, and similar finicky errors that mean your code is
*almost* right. I especially hate them when I'm not sure which direction I'm
off by one. If you have unit tests that are failing, sometimes its quicker and
easier to randomly perturb the specific piece of code until you get the right
answer, rather than trying to analyse it.

"Should I add one here? Maybe subtract one? Start at zero or one? Ah bugger it,
I'll try them all and see which one works."

This is only effective when you have exhaustive tests that exercise all the
relevant cases and can tell you when you've hit the right solution.

On the other hand, sometimes the bug isn't as clear cut as you thought, and you
really do need to analyse the situation carefully.


> I get the impression that many people here are above average too.
> 
> Personally I think you are being pessimistic about "average"
> programmers.  Perhaps you just know the sloppy kind.

One needs to only look at the quality of software, whether open source or
commercial closed source, to feel pessimistic about the ability of even
excellent programmers to write good, secure, bug-free code.

The complexity of code increases faster than our ability to manage that
complexity.



-- 
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: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Steve D'Aprano
On Fri, 29 Sep 2017 07:11 pm, Wolfgang Maier wrote:

> On 29.09.2017 11:05, Wolfgang Maier wrote:
>> On 29.09.2017 07:25, Steve D'Aprano wrote:
>>> I'm pretty sure this is a bug.
>>>
>> 
>> Yes, it is a bug, but a known one: https://bugs.python.org/issue20491
>> 
>> The fix got backported even to 3.5, but I guess it depends which minor
>> version you are running. I'm pretty sure that explains why people report
>> different outcomes.
>> 
>> Best,
>> Wolfgang
>> 
> 
> To be specific, this should be fixed from 3.5.3 and 3.6.0b3 onwards.

Thanks everyone who answered.




-- 
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: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Vincent Vande Vyvre

Le 29/09/17 à 08:58, Frank Millman a écrit :
"Steve D'Aprano"  wrote in message 
news:59cde998$0$14935$b1db1813$d948b...@news.astraweb.com...


On Fri, 29 Sep 2017 03:55 pm, Terry Reedy wrote:


Expected result:


Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.


On Windows 10, I get this on 2.7, 3.5, 3.6, 3.7.


Actual result in Python 3.5 and older:

Lorum ipsum dolor sit amet, consectetur adipiscing elit ZZZ
ZZZ sed do euismod tempor incididunt ut labore et dolore
magna aliqua.


Sorry Terry, it isn't clear to me which result (expected, or actual) 
is "this"

in your comment.


I was also unsure, so to double-check myself I ran this from the 
prompt (Windows 10), not from the interpreter -


C:\Users\User>type aib\aib\test_db100.py

import textwrap
text = ('Lorum ipsum dolor sit amet, consectetur adipiscing'
   ' elit ZZZ\xa0ZZZ sed do euismod tempor incididunt'
   ' ut labore et dolore magna aliqua.')
print()
print(textwrap.fill(text, 59))

C:\Users\User>py -3.5 aib\aib\test_db100.py

Lorum ipsum dolor sit amet, consectetur adipiscing elit ZZZ
ZZZ sed do euismod tempor incididunt ut labore et dolore
magna aliqua.

C:\Users\User>py -3.6 aib\aib\test_db100.py

Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.

It confirms that the problem was there in 3.5, but is fixed in 3.6.

Frank Millman



Python 3.6.1 in venv

Python 3.6.1 (default, Apr 16 2017, 16:15:46)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import textwrap
>>> text = ('Lorum ipsum dolor sit amet, consectetur adipiscing'
... ' elit ZZZ\xa0ZZZ sed do euismod tempor incididunt'
... ' ut labore et dolore magna aliqua.')
>>> print(textwrap.fill(text, 59))
Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.


Vincent

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


Re: Refactoring (was: Spacing conventions)

2017-09-29 Thread Chris Angelico
On Sat, Sep 30, 2017 at 12:45 AM, Stefan Ram  wrote:
> Chris Angelico  writes:
>>If the behaviour remains *exactly* the same, then it's a code
>>improvement (aka a refactoring), not a bug fix.
>
>   Usually, one cannot observe whether behavior stays the same,
>   because a program does not map to behavior, but rather to an
>   entity that produces behavior during an /interaction/ with
>   the world.

And that's why you read source code.

>   For example, I can change
>
> x=float(input()); print( x * 2 )
>
>   to
>
> x=float(input()); print( x * 2 ) \
> if not __import__('random').random() == x else 0
>
>   . The new code has not the same "behavior" in a certain
>   sense. But what do we mean by "behaviour" here? Not
>   something one actually can observe! Because whenever
>   I start the program it behaves just as before the change.

That's also true of a lot of actual real-world bug fixes, though.
Programs don't tend to have as many glaringly obvious bugs as they
have little subtle issues or edge cases. Imagine fixing something that
only occurs if the computer's clock is in the middle of a DST fold and
then you change timezone, for instance. That's about as likely as the
example you give. But it's still not refactoring - refactoring is
where there is not meant to be ANY behavioural change at all.

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


Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Terry Reedy

On 9/29/2017 2:35 AM, Steve D'Aprano wrote:

On Fri, 29 Sep 2017 03:55 pm, Terry Reedy wrote:


Expected result:


Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.


On Windows 10, I get this on 2.7, 3.5, 3.6, 3.7.



Sorry Terry, it isn't clear to me which result (expected, or actual) is "this"
in your comment.


The expected result.  I also should have specified 3.5.4, etc, which 
Wolfgang reported should have the backported fix.  So, you are correct 
that what you saw is/was a bug.


--
Terry Jan Reedy

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread leam hall
On Fri, Sep 29, 2017 at 10:52 AM, justin walters  wrote:

>
> I got through writing all of the above without realizing that you meant you
> wanted to build a
> desktop application and not a web application. Though, I think the advice
> is still helpful.
>
>
Yes and no. Seriously thanks!

I am at first targeting a desktop app just to be simpler and to push me to
learn Tkinter. However, it's more likely to end up a simple web app once I
learn enough Bottle/Flask to make it work. Or I may just skip Tkinter for
the nonce and see if I can do it with web forms.

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread justin walters
On Fri, Sep 29, 2017 at 2:57 AM, Leam Hall  wrote:

> On 09/27/2017 10:33 PM, Stefan Ram wrote:
>
>Some areas of knowledge follow, a programmer should not be
>>ignorant in all of them:
>>
>
> ---
>
> Stefan, this is list AWESOME!
>
> I have started mapping skills I have to the list and ways to build skills
> I don't have. Last night I started working on a project that has been on my
> mind for over a year; taking a CSV list of game characters and putting them
> into a MongoDB datastore. Now I need to figure out how to build an
> interface for CRUD operations using Python, pymongo, and maybe Tk.
>
> I appreciate the structure your list provides. Thank you!
>
> Leam
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Python web backends just happen to be my specialty. I do mostly Django, but
it doesn't
mesh well with MongoDB. Well, it does if you still use an RDBMS forsome
things.

I can recommend the following:

- Flask: http://flask.pocoo.org/
Small and light But not tiny. Not really fast, not really slow. Not a
ton of batteries included.
Tons of third-party extensions.

- ApiStar: https://github.com/encode/apistar
New kid on the block. Specializes in APIS. No template integrations.
Best for serving
JSON through a RESTful interface. Fairly quick, but not blazing fast.
Has the upside that any
web API can be exposed as a CLI API. Not a ton of third party
extensions available. Would
be a good choice if you don't want to build a desktop application
instead of a web application
as it will help design the API that something like Tkinter will sit on
top of.

- Sanic: https://github.com/channelcat/sanic
Another new kid. Python 3.5+ only. Uses the new async capabilities
quite heavilly.
Based on falcon. Blazing fast. No batteries included. Small number of
fairly high
quality third-party extensions.

- Django: https://www.djangoproject.com/
The old workhorse. Mature and proven. Best choice for reliability. Not
fast, not slow.
Huge collection of third party extensions ranging in quality. Though,
it is pretty heavilly
integrated with it's relational Db backends. If you decide on this, you
would need to
use postgres/sqlite/mysql to store all of Django's built in model
classes(tables).

I got through writing all of the above without realizing that you meant you
wanted to build a
desktop application and not a web application. Though, I think the advice
is still helpful.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Chris Angelico
On Fri, Sep 29, 2017 at 8:34 PM, D'Arcy Cain  wrote:
> On 09/29/2017 03:15 AM, Steve D'Aprano wrote:
>>
>> "Carefully-designed experiments" -- yeah, that is so totally how the
>> coders I've
>> worked with operate *wink*
>>
>> I think that's an awfully optimistic description of how the average
>> programmer
>> works :-)
>
>
> Better not hire average programmers then.  I do "Carefully-designed
> experiments" to find non-obvious bugs so I guess I am not average.  I get
> the impression that many people here are above average too.
>
> Personally I think you are being pessimistic about "average" programmers.
> Perhaps you just know the sloppy kind.

Based on any mathematical definition of "average", yes, I am pretty
pessimistic about the average programmer :)

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread D'Arcy Cain

On 09/29/2017 03:15 AM, Steve D'Aprano wrote:

"Carefully-designed experiments" -- yeah, that is so totally how the coders I've
worked with operate *wink*

I think that's an awfully optimistic description of how the average programmer
works :-)


Better not hire average programmers then.  I do "Carefully-designed 
experiments" to find non-obvious bugs so I guess I am not average.  I 
get the impression that many people here are above average too.


Personally I think you are being pessimistic about "average" 
programmers.  Perhaps you just know the sloppy kind.


--
D'Arcy J.M. Cain
Vybe Networks Inc.
http://www.VybeNetworks.com/
IM:da...@vex.net VoIP: sip:da...@vybenetworks.com
--
https://mail.python.org/mailman/listinfo/python-list


Re: OT: Drain specialist Was: Beginners and experts

2017-09-29 Thread Thomas Jollans
On 2017-09-28 14:14, Neil Cerutti wrote:
> On 2017-09-28, Dan Sommers  wrote:
>> If I'm hiring myself out as a plumber, I should know how to unclog
>> drains;
> 
> OT: I recommend hiring a drain specialist, *not* a plumber for
> this particular job. Asking a plumber to clear a drain would be
> kinda like hiring a whiz-bang C programmer to configure your
> email server--it isn't that he or she *can't* do it... 
> 

You mean like Tuppy Glossop's Plumbo-Jumbo, I assume?
https://www.flickr.com/photos/leff/7746149

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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Leam Hall

On 09/27/2017 10:33 PM, Stefan Ram wrote:


   Some areas of knowledge follow, a programmer should not be
   ignorant in all of them:


---

Stefan, this is list AWESOME!

I have started mapping skills I have to the list and ways to build 
skills I don't have. Last night I started working on a project that has 
been on my mind for over a year; taking a CSV list of game characters 
and putting them into a MongoDB datastore. Now I need to figure out how 
to build an interface for CRUD operations using Python, pymongo, and 
maybe Tk.


I appreciate the structure your list provides. Thank you!

Leam

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


Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread breamoreboy
On Friday, September 29, 2017 at 6:46:31 AM UTC+1, Frank Millman wrote:
> "Steve D'Aprano"  wrote
> 
> I don't have Python 3.6 installed, can somebody check to see whether or not 
> it
> shows the same (wrong) behaviour?
> 
> [...]
> 
> C:\Users\User>python
> Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit 
> (AMD64)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import textwrap
> >>> text = ('Lorum ipsum dolor sit amet, consectetur adipiscing'
> ... ' elit ZZZ\xa0ZZZ sed do euismod tempor incididunt'
> ... ' ut labore et dolore magna aliqua.')
> >>> print(textwrap.fill(text, 59))
> Lorum ipsum dolor sit amet, consectetur adipiscing elit
> ZZZ ZZZ sed do euismod tempor incididunt ut labore et
> dolore magna aliqua.
> >>>
> 
> It seems to have been fixed.
> 
> Frank Millman

FTR https://bugs.python.org/issue20491

--
Kindest regards.

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


Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Wolfgang Maier

On 29.09.2017 11:05, Wolfgang Maier wrote:

On 29.09.2017 07:25, Steve D'Aprano wrote:

I'm pretty sure this is a bug.



Yes, it is a bug, but a known one: https://bugs.python.org/issue20491

The fix got backported even to 3.5, but I guess it depends which minor 
version you are running. I'm pretty sure that explains why people report 
different outcomes.


Best,
Wolfgang



To be specific, this should be fixed from 3.5.3 and 3.6.0b3 onwards.

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


Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Wolfgang Maier

On 29.09.2017 07:25, Steve D'Aprano wrote:

I don't have Python 3.6 installed, can somebody check to see whether or not it
shows the same (wrong) behaviour?


import textwrap
text = ('Lorum ipsum dolor sit amet, consectetur adipiscing'
 ' elit ZZZ\xa0ZZZ sed do euismod tempor incididunt'
 ' ut labore et dolore magna aliqua.')
print(textwrap.fill(text, 59))



Expected result:


Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.


Actual result in Python 3.5 and older:


Lorum ipsum dolor sit amet, consectetur adipiscing elit ZZZ
ZZZ sed do euismod tempor incididunt ut labore et dolore
magna aliqua.


I'm pretty sure this is a bug.



Yes, it is a bug, but a known one: https://bugs.python.org/issue20491

The fix got backported even to 3.5, but I guess it depends which minor 
version you are running. I'm pretty sure that explains why people report 
different outcomes.


Best,
Wolfgang


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


Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Thomas Jollans
On 2017-09-29 08:58, Frank Millman wrote:
> 
> It confirms that the problem was there in 3.5, but is fixed in 3.6.
> 

Same on Linux: 3.5 has the bug, 3.6 doesn't.

(Python 3.5 from Red Hat, 3.6 from Anaconda)


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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Bill

Steve D'Aprano wrote:


(say). Reading error messages is a skill that must be learned, even in Python.
Let alone (say) gcc error messages, which are baroque to an extreme. The other
day I was getting an error like:

/tmp/ccchKJVU.o: In function `__static_initialization_and_destruction_0(int,
int)':
foo.cpp:(.text+0x7c): undefined reference to `std::ios_base::Init::Init()'
foo.cpp:(.text+0x91): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status




Yes, that's the sort of character-building that I was referring to (that 
a beginner needs to learn!)They have to learn that if it "breaks", 
then there must be a simpler way to break it!  Hopefully one which will 
satisfy Log_2 (n).: )


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


Re: Beginners and experts (Batchelder blog post)

2017-09-29 Thread Steve D'Aprano
On Fri, 29 Sep 2017 03:28 pm, Gregory Ewing wrote:

> Chris Angelico wrote:
>> finding the bug is basically searching
>> through a problem space of all things that could potentially cause
>> this symptom. A novice could accidentally stumble onto the right
>> solution to a tricky bug, or an expert could search a thousand other
>> things and only get to the true cause after a long time.
> 
> What I think is more important than how *long* it takes is
> *how* they go about finding the bug.
> 
> A novice will make wild guesses about what might be wrong
> and make random changes to the program in the hope of
> making it work. An experienced programmer will conduct
> a series of carefully-designed experiments to narrow
> down the cause.

"Carefully-designed experiments" -- yeah, that is so totally how the coders I've
worked with operate *wink*

I think that's an awfully optimistic description of how the average programmer
works :-)


> A result of this is that a true expert will never have
> to try a thousand possibilities. He will be able to
> search a space of N possible causes in O(log N) operations.

I don't think that, *in general*, possible causes of a bug can be neatly sorted
in such a way that we can do a binary search over the space of all possible
causes.

I also think it is unlikely that even the best programmer enumerates all the
possible causes before working on them. If you don't enumerate all the causes
first, how to you sort them?

In my experience, even good coders are likely to say "there's only three
possible things that could be causing this bug", and later on report it was
actually the fifth thing.

More likely, the experienced programmer is better at eliminating irrelevancies
and narrowing in on the space of likely candidates, or at least narrowing down
on the region of code that is relevant, while less experienced programmers
waste more time looking at things which couldn't possibly be the cause[1].

More likely, the experienced programmer makes better use of his or her tools.
While the novice is still messing about trying to guess the problem by pure
logical reasoning, the expert is using a few useful print calls, or a debugger,
to narrow down to where the problem actually is.

And experts are likely to be better at extrapolating "well, since that's not the
problem... maybe its this?". And you learn that not by pure logic, but by being
bitten by nasty bugs:

"I can't see any possibly way that this could be involved, but I came across a
similar situation once before and this was the solution... [confirms hypothesis
and fixes bug] oh of course, that's how the bug occurs! Its obvious in
hindsight."

More experienced programmers are confident enough to know when to walk away from
a problem and let their subconscious work on it. Or when to go and explain it
to the cleaning lady[2]. Or when to admit defeat and hand over to a fresh pair
of eyes who won't be stuck in the same mindset.

Even just getting to the point of being able to reason *where to start* requires
a fair amount of experience. A true beginner to programming altogether won't
even know how to read a stack trace to identify the line where the bug occurs,
let alone understand why it happened. I wish I had a dollar for every time some
beginner says something like:

"I get a syntax error. What's wrong with my code?"

and eventually after much arm-twisting is convinced to post the last line of the
traceback, which turns out not to be a syntax error at all:

"TypeError: object of type 'int' has no len()"

(say). Reading error messages is a skill that must be learned, even in Python.
Let alone (say) gcc error messages, which are baroque to an extreme. The other
day I was getting an error like:

/tmp/ccchKJVU.o: In function `__static_initialization_and_destruction_0(int,
int)':
foo.cpp:(.text+0x7c): undefined reference to `std::ios_base::Init::Init()'
foo.cpp:(.text+0x91): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status


Of course, its obvious that the problem here is that I needed to install g++ as
well as gcc, right? :-)


> This doesn't necessarily translate into time, because
> in some situations the experiments can be very time-
> consuming to perform. But other things being equal,
> the expert's bug-finding algorithm is faster than the
> novice's.





[1] Although, the *really* experienced programmer knows that in sufficiently
baroque and highly-coupled code, a bug could be caused by *anything*
*anywhere*. (This is one reason why global variables are bad.)

I still haven't gotten over hearing about a bug in the Internet Explorer
routines for handling WMF files, which lead to being unable to copy and paste
plain text in any application.


[2] The place I worked had a cuddly penguin toy called Mr Snuggles, and the
programmers would go and explain the problem to him. It never[3] failed.

[3] Well, hardly ever.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, a

Re: Textwrap doesn't honour NO-BREAK SPACE

2017-09-29 Thread Frank Millman
"Steve D'Aprano"  wrote in message 
news:59cde998$0$14935$b1db1813$d948b...@news.astraweb.com...


On Fri, 29 Sep 2017 03:55 pm, Terry Reedy wrote:


Expected result:


Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.


On Windows 10, I get this on 2.7, 3.5, 3.6, 3.7.


Actual result in Python 3.5 and older:

Lorum ipsum dolor sit amet, consectetur adipiscing elit ZZZ
ZZZ sed do euismod tempor incididunt ut labore et dolore
magna aliqua.


Sorry Terry, it isn't clear to me which result (expected, or actual) is 
"this"

in your comment.


I was also unsure, so to double-check myself I ran this from the prompt 
(Windows 10), not from the interpreter -


C:\Users\User>type aib\aib\test_db100.py

import textwrap
text = ('Lorum ipsum dolor sit amet, consectetur adipiscing'
   ' elit ZZZ\xa0ZZZ sed do euismod tempor incididunt'
   ' ut labore et dolore magna aliqua.')
print()
print(textwrap.fill(text, 59))

C:\Users\User>py -3.5 aib\aib\test_db100.py

Lorum ipsum dolor sit amet, consectetur adipiscing elit ZZZ
ZZZ sed do euismod tempor incididunt ut labore et dolore
magna aliqua.

C:\Users\User>py -3.6 aib\aib\test_db100.py

Lorum ipsum dolor sit amet, consectetur adipiscing elit
ZZZ ZZZ sed do euismod tempor incididunt ut labore et
dolore magna aliqua.

It confirms that the problem was there in 3.5, but is fixed in 3.6.

Frank Millman


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