Re: [Tutor] Long Lines techniques

2018-12-14 Thread Avi Gross
<[{SYNOPSIS: Many good answers. I am satisfied and we can move on.}]>

Steven,

I appreciate the many useful suggestions.

Many of them are what I already do. Some are in tension with other
considerations. Yes, it can be shorter and more efficient to not keep saying
module.this.that.something versus something like:

>From module.this.that import something as myname.

Of course you do that with care as you want to be careful about pulling too
many things into collisions in one namespace. Longer more descriptive names
are encouraged.

Based on reading quite a bit of code lately, I do see how common it is to
try to shorten names while not polluting the namespace as in the nearly
universal:

Import numpy as np, pandas as pd

The places I like to wrap lines tend to be, in reality, the places python
tolerates it. If you use a function that lets you set many options, it is
nice to see the options one per line. Since the entire argument list is in
parentheses, that works. Ditto for creating lists, sets and dictionaries
with MANY items at once. 

There are cases where it may make sense to have a long like connected by AND
or OR given how python does short-circuiting while returning the last thing
or two it touched instead of an actual True/False. For example, you may want
to take the first available queue that is not empty with something like
this:

Using = A or B or C or ... or Z
Handling = Using.pop()

Sure, that could be rewritten into multiple lines. 

I won't get sucked into a PERL discussion except to say that some people
love to write somethings so obscure they won't recognize it even a daylater.
PERL makes that very easy. I have done that myself a few times as I was an
early user. Python may claim to be straightforward but I can easily see ways
to fool people in python too with dunder methods or function closures or
decorators or ...

All in all, I think my question has been answered. I will add one more
concept.

I recently wrote some code and ran into error messages on lines I was trying
to keep short:

A = 'text"
A += "more text"
A += object
A+= ...

At one point, I decided to use a formatted string instead:

A = f"...{...}...{...}..."

Between curly braces I could insert variables holding various strings. As
long as those names were not long, and with some overhead, the line of code
was of reasonable size even if it expanded to much more.

-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Thursday, December 13, 2018 7:27 PM
To: tutor@python.org
Subject: Re: [Tutor] Long Lines techniques

On Thu, Dec 13, 2018 at 12:36:27PM -0500, Avi Gross wrote:

> Simple question:
> 
> When lines get long, what points does splitting them make sense and 
> what methods are preferred?

Good question!

First, some background:

Long lines are a potential code smell: a possible sign of excessively terse
code. A long line may be a sign that you're doing too much in one line.

https://martinfowler.com/bliki/CodeSmell.html
http://wiki.c2.com/?CodeSmell
https://blog.codinghorror.com/code-smells/

Related: 
https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/

Note that merely splitting a logical line over two or more physical lines
may still be a code-smell. Sure, your eyes don't get as tired reading
fifteen lines of 50 characters each, compared to a single 750 character
line, but there's just as much processing going on in what is essentially a
single operation.

Long lines are harder to read: your eyes have to scan across a long line,
and beyond 60 or 70 characters, it becomes physically more difficult to scan
across the line, and the error rate increases. 
[Citation required.]

But short lines don't include enough information, so the traditional
compromise is 80 characters, the character width of the old-school
green-screen terminals. The Python standard library uses 79 characters. 
(The odd number is to allow for scripts which count the newline at the end
of the line as one of the 80.)

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


Okay, so we have a style-guide that sets a maximum line length, whether it
is 72 or 79 or 90 or 100 characters. What do you do when a line exceeds that
length?

The only firm rule is that you must treat each case on its own merits. 
There is no one right or wrong answer. Every long line of code is different,
and the solution will depend on the line itself. There is no getting away
from human judgement.


(1) Long names. Do you really need to call the variable
"number_of_characters" when "numchars" or even "n" would do?

The same applies to long function names: "get_data_from_database" is
probably redundant, "get_data" will probably do.

Especially watch out for long dotted names that you use over and over again.
Unlike static languages like Java, each dot represents a runtime lookup.
Long names like:

package.subpackage.module.object.method

requires four lookups. Look for oportunities to make an alias for a long
name and avoid long chains of dots:

 

Re: [Tutor] Python function

2018-12-14 Thread Avi Gross
If you know what a CommaSeparatedValues file looks like, then reading ONE
LINE gives you enough info to answer the question about how many columns of
data it describes. 

-Original Message-
From: Tutor  On Behalf Of
Alan Gauld via Tutor
Sent: Thursday, December 13, 2018 7:47 PM
To: tutor@python.org
Subject: Re: [Tutor] Python function

On 13/12/2018 17:21, Sammy Lee wrote:
> How do I create a python function that opens a CSV file and determines 
> how many columns of data are in the file? The CSV files have been 
> randomly generated from https://www.mockaroo.com/
> 
> def csv_column_count(openfile):

You will find a bunch of stuff on creating functions in the Functions and
Modules topic of my tutorial.(see below)

You will find a bunch of stuff on handling files in the Handling Files topic
of my tutorial.(see below)

You will find a lot of help on using CSV files in the csv module
documentation in the standard library. (Or you could buy my book "Python
Projects" which has a section on the topic.)



--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Long Lines techniques

2018-12-14 Thread Avi Gross
Steve[n],

Yes, I figured out what the problem was but while evaluating I also realized
that a format string was an ALTERNATIVE that automatically called for an str
or repr so in a sense it would work without debugging. 

I find that sometimes the long lines make it harder to see the skeleton of
the logic as you get bogged down by things that may be of lesser importance.

So I close with another idea. I asked about functions with lots of
arguments. An example might be making a graph using a library that lets you
specify literally hundreds of parameters all at once. I realized that a
perfectly valid alternative to make the main purpose more reasonable would
be to stuff all the extra arguments in a dictionary like

Other_args = { this: value,
That : value,
...
}
That is something in braces that can be wrapped for legibility.

Then the main function call can use the **  expansion like so:

Ret = function(from, to, **Other_args)

Of course, you can also use * with a list or other iterable for the
positional args when that makes it easier but at some point you no longer
have a feel as to what the function call is doing. But hiding less important
details this way seems to be good. Not sure about run-time efficiency, of
course.

-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Friday, December 14, 2018 12:22 AM
To: tutor@python.org
Subject: Re: [Tutor] Long Lines techniques

On Thu, Dec 13, 2018 at 11:07:59PM -0500, Avi Gross wrote:

[...]
> There are cases where it may make sense to have a long like connected 
> by AND or OR given how python does short-circuiting while returning 
> the last thing or two it touched instead of an actual True/False. For 
> example, you may want to take the first available queue that is not 
> empty with something like
> this:
> 
> Using = A or B or C or ... or Z
> Handling = Using.pop()
> 
> Sure, that could be rewritten into multiple lines. 

using = (A or B
 or C or D 
 or E or F)


[...]
> I recently wrote some code and ran into error messages on lines I was 
> trying to keep short:
> 
> A = 'text"
> A += "more text"
> A += object
> A+= ...

Without knowing the error message, its impossible to say what the problem
is. My guess is that the object on line three wasn't a string. 
In which case, the obvious fix is:

A += str(object)



--
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Obfuscated Python [was Long Lines techniques]

2018-12-14 Thread Avi Gross
Steven,

There are dunderheads who will maliciously misuse things. Yes, we know what
__add__ is supposed to do. But if someone codes a class with one that
ignores addition to a collection if it has reached a maximum size, or does
addition modulo 16 or makes it play a happy birthday tune, while
subtracting, it may not be trivial for the innocent user of your code to
make much sense of it. 

There are documented IDEAS about what many of those dunder methods might
mean but no enforcement. 

I remember an Abstract Algebra course I took where we often talked about
operations like + and * in very abstract ways and came up with some
fascinating meanings to the operations. An example might be the various
definitions of multiplication for vectors or matrices. When you multiply,
are you multiplying corresponding parts or are you multiplying a row times a
column and summing the multiplications for each slot in the matrix? Or could
multiplication be a tad more complex and require also taking a transpose
first? Or perhaps getting a determinant or eigenvalues or eigenvectors? What
does it mean to add "1" to a complex number or quaternion or octonion? 

The reality is that two people can often try to make a similar class and
come up with different ideas and implementations. If I have a class
representing people who RSVP for a party, might a PLUS of a person result in
upping the party count by 2 since we assume they are bringing a date and if
their presence requires another table, upping that count and so on? A simple
__add__ can result in many things such as checking the added person for
dietary needs and adjusting more stuff just because adding a person can be
complex.

You re not going to sucker me into discussing obfuscation today. Some people
here got touchy last time.

I am not defending PERL nor slamming Python. I am saying people who behave
well will try to avoid writing code that is hard to read and may be
understood in multiple ways. There are cute ways to do things in many
languages.

Last comment, in what some might call stream of consciousness. Python allows
a function to return without an explicit return. Usually it returns None but
I not in some generators it may throw an exception instead. The problem is
that if you are not looking carefully at indentation, you might thing the
statements that follow may be part of the same function. So my personal
preference is to have an explicit return instead of letting it drop out of
the function or at least a comment saying this is the end of the function.
Similarly, many people won't close a file (I am not talking about in a with
statement) or delete variables no longer in use, and depend on these things
happening automatically eventually. There may be nothing wrong with that,
especially for smaller programs. But a part of me appreciates when the
scales are visibly balanced. But when overdone, as in a function where every
statement is in its own try/catch even for problems very unlikely to happen,
there is too muc detail to follow. Something in between seems more
comfortable. So interrupting an algorithm to del no longer needed variables
may not be best either. To each their own.

-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Friday, December 14, 2018 12:36 AM
To: tutor@python.org
Subject: [Tutor] Obfuscated Python [was Long Lines techniques]

On Thu, Dec 13, 2018 at 11:07:59PM -0500, Avi Gross wrote:

> Python may claim to be straightforward but I can easily see ways to 
> fool people in python too with dunder methods or function closures or 
> decorators or ...

Dunder methods shouldn't fool anyone. Each dunder method has a
straightforward use, and most of the time you can guess that they do. 
__add__ implements the + operator, etc.

Closures and decorators can be abused, as can anything. One can write
obfuscated code in any language. Here's some amusing obfuscated Python:

https://www.reddit.com/r/Python/comments/i1qgp/reduce_and_lambda_two_great_t
astes_that_taste/

https://mail.python.org/pipermail/python-list/2013-October/658470.html

Anyone else want to share some obfuscated Python code?



--
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Obfuscated Python [was Long Lines techniques]

2018-12-14 Thread Mats Wichmann
On 12/13/18 11:15 PM, Avi Gross wrote:
> Steven,
> 
> There are dunderheads who will maliciously misuse things. Yes, we know what
> __add__ is supposed to do. But if someone codes a class with one that
> ignores addition to a collection if it has reached a maximum size, or does
> addition modulo 16 or makes it play a happy birthday tune, while
> subtracting, it may not be trivial for the innocent user of your code to
> make much sense of it. 
> 
> There are documented IDEAS about what many of those dunder methods might
> mean but no enforcement. 

As Raymond Hettinger likes to say, Python is a Consenting Adults
language.  You're not prevented from doing things, even if it might
outrage a few...


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor