Re: Friday Finking: Contorted loops
On 2021-09-11 21:38:02 -0400, Avi Gross via Python-list wrote: > Peter, in your own personal finite sample, I am wondering what you might do > TODAY if you looked at your loops again and considered redoing them for an > assortment of reasons ranging from using the code for teaching to efficiency > to just fitting your mood better? > > I have seen seasoned authors go back to their early work and groan. Yeah, I do that. (Un)fortunately I also have other people's code to groan about so I won't despair too much about the stupidity of my younger self. > My guess is that many of us (meaning myself included) often approach a > problem and go with the first thing that comes to mind. If it fits well > enough, we move on to the next thing we can do. If not, we may step back and > evaluate multiple additional options and try another tack. > > I have seen not of sort-of redundant code because someone did not plan ahead > and realize something very similar might be needed later and thus did not > make a general function they could re-use. Occasionally they may later go > back and re-do but often, not so much and just keep copying lines and making > minor modifications. Same general idea. That certainly happens. I am a bit overly conservative and try to get away with minimal code changes even if a complete reimplementation of that unit would be clearly better. Especially if it's someone else's code and there are no unit tests. But also for my own code. (As an aside, I notice the same tendency when changing text: Altering an existing paragraph is hard, especially if someone else wrote it. Also, while I think I can express myself quite clearly in both German and English, I'm rarely satisfied when I try to translate between those languages. I always stick too close to the original). > And perhaps worse, you may write a loop and later have to keep adding code > to deal with new requirements and special cases and rather than pause and > analyze and perhaps start again with a cleaner or more easily extendable > solution, just keep grafting on things to make the darn current code work. > Code that has many ways to exit a loop is often an example of this > happening. That too. Those little C utilities I mentioned are probably a bad example because they are so small and had little reason to evolve. But I do have Perl scripts which I originally wrote 20 years ago and which are still in use and have been adapted to changing business requirements again and again in that time. Those do contain some gnarly code. > So if you looked at your own code now, in the context of the rest of your > code, would you change things? Almost certainly. Especially in C I would probably be more cautious about undefined behaviour now and for different reasons. Back in the 90's I mostly worried about portability: That code could one day run on a 36-bit ones-complement machine with 9-bit chars. These I days I worry more about overly aggressive optimizations: That pointer is accessed here so it can't be null, so it can't be null here either so that check can be optimized away. I started using Python only 7 years ago, when I had already been using Perl for almost 20 and C for over 25 years. So my older Python code probably looks a bit "perly". So they use dicts and map and filter but not list comprehensions for example. Also some of that code was partially inherited from other Python programmers who adhered to the "a real programmer can write Fortran in any language" mindset. > So when counting the various kinds, are you looking for direct or indirect > methods too like map/reduce or vectorized operations? No, because that wasn't the question I was trying to answer. The question was "do people use do/while loops frequently in languages which provide them"? I chose C (mostly because it is easier to get useful numbers with tools like grep and wc than with Perl) and therefore only the types of loops available in C. (Methodically the main flaw in my approach is that I only looked at a single language and a single person and only a tinly sample from that person. To really answer that question you would have to look at a sizable sample from Github or something like that). hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | [email protected] |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: on floating-point numbers
On 2021-09-11, Chris Angelico wrote: > Once you accept that "perfectly representable numbers" aren't > necessarily the ones you expect them to be, 64-bit floats become > adequate for a huge number of tasks. Even 32-bit floats are pretty > reliable for most tasks, although I suspect that there's little reason > to use them now - would be curious to see if there's any performance > benefit from restricting to the smaller format, given that most FPUs > probably have 80-bit or wider internal registers. Not all CPUs have FPUs. Most of my development time is spent writing code for processors without FPUs. A soft implementation of 32-bit FP on a 32-bit processors is way, way faster than for 64-bit FP. Not to mention the fact that 32-bit FP data takes up half the memory of 64-bit. There are probably not many people using Python on 32-bit CPUs w/o FP. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 11/09/2021 15:41, Peter J. Holzer wrote:
> How is C's do/while loop more horrible than Pascal's repeat/until?
Because it is very hard to spot or distinguish from a normal
while loop.
while condition ;
Is a valid (and fairly common) loop in C
so code that has
do{
code
}
while condition;
Looks, for non-trivial cases, like a lot of code followed
by an empty while loop.
The do is easy to miss and the while loop disguised as
a repeat termination is confusing.
repeat
code
until condition
Is far clearer to comprehend since there is no ambiguity.
> In an old collection of small C programs of mine I find:
>
> 35 regular for loops
> 28 while loops
> 2 infinite for loops
> 1 "infinite" for loop (i.e. it exits somewhere in the middle)
> 0 do/while loops.
That wouldn't surprise me, I've only used do/while in C
a handful of times. But in Pascal I use it regularly.
--
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
--
https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
-- snip --
An inconsistency that I have been able to notice is this:
someone suggests to remedy the absence of the do-while with:
while True:
...
if condition:
break
the problem arises if the while has an else of its own because the break
not only blocks the while loop but will also ignore the relative else.
I will try to make my doubt clearer:
if the only way to terminate a 'while True' loop is by using the 'break'
statement, why is it allowed to add the 'else' statement which will only
contain dead code?
while True:
break
else:
print('dead code')
--
https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
[email protected] (Stefan Ram) writes: > Alan Gauld writes: >>OK, That's a useful perspective that is at least consistent. >>Unfortunately it's not how beginners perceive it > ... > > Beginners perceive it the way it is explained to them by > their teacher. My life as a professor would have been *so* much easier if that were true... -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On Sun, 12 Sep 2021 10:11:15 +0200, jak wrote:
> -- snip --
>>
>> An inconsistency that I have been able to notice is this:
>> someone suggests to remedy the absence of the do-while with:
>> while True:
>> ...
>> if condition:
>> break
>> the problem arises if the while has an else of its own because the
>> break not only blocks the while loop but will also ignore the relative
>> else.
>>
>>
> I will try to make my doubt clearer:
> if the only way to terminate a 'while True' loop is by using the 'break'
> statement, why is it allowed to add the 'else' statement which will only
> contain dead code?
>
> while True:
> break
> else:
> print('dead code')
Because adjusting the parser for one specific special case is not worth
the effort.
it is not the job of the interpreter to sanitise stupid programming
"Special Cases aren't special enough the break the rules"
--
If you stew apples like cranberries, they taste more like prunes than
rhubarb does.
-- Groucho Marx
--
https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
Il 11/09/2021 22:29, Avi Gross ha scritto:
Alan and others,
I think human languages used to make computer languages will often cause
confusion.
Some languages have an IF .. ELSE construct but also an EITHER ... OR and a
NEITHER ... NOR and other twists and turns like words that sometimes come
apart and you end up having to dangle a part that was in the front of a word
to later in the sentence and so on.
But I suspect many languages do NOT naturally have a construct like:
WHILE ... ELSE.
The might have a sentence like "While it is sunny you should use sunscreen
but when it rains use an umbrella." It probably is even a tad deceptive to
use WHILE in one part and not in the other. Perfectly valid sentences are
"When going outside if it is sunny use sunscreen but if it is rainy use an
umbrella" or skip the while and use a more standard if/else. The world
"while" just does not feel like a partner for "else".
So say you want to have a loop starting with WHILE and FOLLOWED by a single
ELSE clause. Arguably you could make WHILE as a construct return a status of
sorts if it runs at all or perhaps if it exits after at least one iteration
because the condition evaluates to FALSE. It would either return false if
you exit with a BREAK or by an error or perhaps not exit at all if you do a
return from within.
So if you made up a syntax like:
IF (WHILE condition {...})
ELSE {...}
Then what would that mean? Again, this is a make-believe construct. In the
above, if WHILE returned a True of some sort, the else is skipped.
Otherwise, no matter what has been done within the while loop, it is done.
But as noted we have odd choices here potentially. Could we differentiate
between a BREAK statement within and something like BREAK OK variant that
means the while is to be treated as succeeded and please do not do the
trailing ELSE? I can see many possible ways to design things and cannot
expect humans to automatically assume the specific nomenclature will be
meaningful to them.
There is an alternative that people who are not damn sure what the meaning
is can do. Create a variable that is set to False or True to represent
something before the WHILE is entered. Then make sure your code flips that
value in cased you want to make sure a trailing statement is run. Then
following the while, you place an IF statement that tests that variable and
does what the ELSE cluse would have done, or not.
Looking at other constructs, look at this code with a try:
i=0
while i<5:
try:
assert(i!=3) #Raises an AssertionError if i==3
print("i={0}".format(i))
except:
continue
finally:
i+= 1; #Increment i
Now attach an ELSE clause to the WHILE, LOL!
At some point, van some humans decide just not to write the code this way?
What about code that uses CONTINUE to the point where you enter the WHILE
statement and get a secondary IF or something that keeps triggering a
CONTINUE to start the next iteration. Arguably, this can effectively mean
the WHILE loop did nothing. An example would be evaluating the contents of a
data structure like a list and adding all numeric items together and
ignoring any that are character strings. Given all characters, no summation
is done. The first statement in the loop tests a list item and does a
CONTINUE. But by the rules as I see them, the loop was entered. Yet, a
similar loop written where the WHILE condition simply tests if ANY item is
numeric, might drop right through to an ELSE clause.
Bottom line is humans do not all think alike and language constructs that
are clear and logical to one may be confusing or mean the opposite to
others.
I can even imagine designing an interface like this:
WHILE (condition):
...
IF_NOT_RUN:
...
IF_EXITED_EARLY:
...
IF_ERROR_THROWN:
...
ON_PREMATURE_RETURN_DO_THIS:
...
I am not suggesting we need critters like that, simply that ELSE is a grab
bag case that can mean many things to many people.
But if the specific meaning is clearly documented, use it. Lots of people
who program in languages like Python do not necessarily even speak much
English and just memorize the keywords.
We can come up with ever more interesting or even bizarre constructs like
multiple WHILE in a row with each one being called only if the previous one
failed to process the data. An example might be if each tests the data type
and refuses to work on it so the next one in line is called. That could
perhaps be done by having multiple ELSE statements each with another WHILE.
But is that an ideal way to do this or perhaps instead use some variant of a
switch statement or a dictionary pointing to functions to invoke or
something.
Time to go do something lese of even minor usefulness!
-Original Message-
From: Python-list On
Behalf Of Alan Gauld via Python-list
Sent: Saturday, September 11, 2021 3:59 AM
To: [email protected]
Subject: Re: Friday Finking: Contorted loops
On 10/09/2021 19:49, Stefan Ram wrote:
Alan Ga
Re: ANN: Version 0.5.1 of the Python config module has been released.
Used by 4.8k but only ... 4 stars -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 2021-09-11 at 18:21:17 +0100,
Alan Gauld via Python-list wrote:
> On 11/09/2021 15:41, Peter J. Holzer wrote:
>
> > How is C's do/while loop more horrible than Pascal's repeat/until?
>
> Because it is very hard to spot or distinguish from a normal
> while loop.
>
> while condition ;
>
> Is a valid (and fairly common) loop in C
>
> so code that has
>
> do{
> code
> }
> while condition;
>
> Looks, for non-trivial cases, like a lot of code followed
> by an empty while loop.
>
> The do is easy to miss and the while loop disguised as
> a repeat termination is confusing.
Well, yeah, except that only a macro would ever write it that way. :-)
At the very least, the code would be indented (making it easier to spot
the "do," before or after you see the while; and my apologies if you
intended it that way and it got lost somewhere between your intent and
my monitor):
do {
code;
}
while(condition);
(Side question: why put the "{" next to the "do," but the "}" and the
"while" on separate lines?)
And I would put the while on the same line as the closing brace (which
is also where I put the "else" in an if statement):
do {
code;
} while(condition);
--
https://mail.python.org/mailman/listinfo/python-list
RE: Friday Finking: Contorted loops
The topic of looping and our current discussion stimulates me to ask if someone has categorized the uses of loops and it seems something obvious. Once you know what kinds of loopy looping there are, it can get easier to decide which, if any, of the methods to set up a loop make more sense. Computer languages differ in all kinds of ways including more subtle ideas of when a variable is within view or not and that can impact looping methods. Years ago, in many languages, loops were used simply to COPY something stored in some array-like format. Languages like C might have a character string stored in a null-terminated array and the accepted way to copy it might be to use pointers called p (the source) and q(the destination) in weird and compact code like: while (*q++ = *p++); Now Python does not have some of those operators but copying strings is fairly trivial with no visible loops but copying some objects (I mean a new and even deep copy) can use loops, albeit for many objects, there is a copy functionality available to do it quietly. If you only want a subset of the values to be taken into a copy, many languages have a subletting method like var[1:5] and often you have functions like map/reduce you can pass things to that return an arbitrary subset based on applying a function. Python has thus quite a few ways to hide any loops involved in copying so you will often not see a WHILE or FOR in sight. For simple (and even sometimes more complex) scenarios, comprehensions of many types can be used in in-line situations. Generators can supply what can amount to a sort of deferred and thus distributed loop that is run interspersed with other things happening. One reason many applications bring in add-on modules like numpy and pandas is because they partially fill some gaps and make many vectorized operations easy. Any operation that works simultaneously on every member in a way that has no conflict with calculations on other members is an example. If I have two vector like objects such as A and B, then being able to write 3*A means modifying all the elements of A to be triple what they were and it does not necessarily need to happen in any order or even be all done by the same process. If A and B are the same length (or logically adjusted to be) then A+B is similarly a vector operation. Quite a few such things are done routinely with no loops visible in the code that once littered my C code. Languages like R (and the original S) were built from the ground up so everything starts with a vector and even a singleton variable is merely a vector of length 1. Many programs simply do not need loops as it is done for you. I have mentioned ways to use objects in Python as a way to hide loops. Of course that implies an object may use methods that contain small loops, such as to search and internal list to see if something is already being held, or to find the end and append another and so on. But you main program may thus often be written without such looks. Functional programming techniques, again, can be used to say apply a function to every item in a list and collect the results in another list or scalar. You will not see a WHILE or a FOR but a loop happens. I have sometimes written a program and then after it was working, took another look and redesigned it in ways that often shorten it substantially and even speed it up. I admit people reading the code often have no clue what it does. So especially for teaching Computer Science, many loops remain a good place to start. My guess is that if, like me, you often avoid using loops in trivial cases, you may end up using them in cases that are more complex. You may end up with mainly cases where you end up having to BREAK or CONTINUE or RETURN from within a loop, perhaps with multiple exit points. Some of those cases may well be much more difficult using the hidden loops. So I was not in any way being negative with Peter about his admittedly restricted sample of coding practices, or of others who searched a body of code by many authors. I am saying that people who write code can evolve and not go back and change older code. I once inherited code that had nested loops about 9 units deep. Something like for in in ... for j in ... for k in ... It was a tad more complex, of course as it tested all variations of categorical variables. There were additional loops in selected places within there, as well. It ran slowly in interpreted form. What I ended up doing was generating a data structure (a data.frame) that contained all combinations and handed that to a function called pmap that did one row at a time by setting variables. The problem became way more tractable and quite a bit faster. And, in this case, I suspect it may have been more readable without getting lost in all the nesting. But not all languages and problems are amenable to some approaches, and some play games with how variables are kept and used. Python has so
RE: Friday Finking: Contorted loops
Stefan, Agreed that writing code to handle all possible eventualities is usually overkill and results in bloated software delivered very late or not at all. My point is that often OTHERS start adding requests afterward that seem trivial to THEM as they have no idea what it takes. I have often done some kind of data analysis for someone and made a few graphs and suddenly they ask if I can add something else to the graph such as a few horizontal lines showing where a danger zone lies, or some kind of average. No problem but to do that means the new info has to have been made available or can be calculated and often even means my function needs to take more arguments or a wider data.frame. Then they reconsider and ask if instead of a line, can I color the background above that point. Well, yeah, but now I might need to calculate another column to use to guide that feature. Ah, but can you show a series of related such graphs as a unit, or perhaps combine several unrelated graphs in a 3 by 2 matrix. Argh! Sure, I can do that but you did not ask me to before I started. I now might toss out much of my original code and rewrite something so all the things needed are made first and then the graphs are made and recombined in the right output format. This means that what used to make a graph will now make a data structure to return that can be used later to recombine into a bigger consolidated graphic. Does the story end here? Nope. Tons more requests like removing color and using shades of gray or dotted lines so it can be printed on any printer, changing the point size of text and other characteristics and introduce mathematical symbols and equations along the axes and I swear an amazing number of such fine tunings including taking a series of these things into one multi-page PDF. If this was a paid gig and someone offered me a fixed sum, should I tolerate almost any changes? If this was a regular paid job and this made me late and not get other things done? My bottom line is that it may not be reasonable to make a detailed top-down design and stock with it BUT that code written by ever-changing requirements can end up badly too. I shudder at times I wrote decent code full of comments explaining well and a while later had a mess where the comments lagged behind changes in the code as there was no point in bothering to update them unless it stopped changing. And, often, by then, I was no longer interested in spending any more time and sometimes just removed all the comments and moved on! Good luck to anyone coming along to maintain or improve the code. I have to think about when to make a function. Something trivial is often not worth is. And making a very abstract function that can do a dozen things if invoked just right with many arguments is sometimes a tad too much when a few simpler functions might do as well with less overhead and especially when the uses have fairly little in common. Some languages may discourage you if the repeated code needs to do things in the current environment and thus only part of the functionality can be moved away. -Original Message- From: Python-list On Behalf Of Stefan Ram Sent: Saturday, September 11, 2021 10:56 PM To: [email protected] Subject: Re: Friday Finking: Contorted loops "Avi Gross" writes: >I have seen not of sort-of redundant code because someone did not plan >ahead From my experience, the "plan ahead" approach (waterfall model) often is less applicable than the "code is design" (Reeve) + "refactoring" (Fowler) approach. (However, in some fields, planning ahead is a requirement). >and realize something very similar might be needed later and thus did >not make a general function they could re-use. Occasionally they may >later go back and re-do but often, not so much and just keep copying >lines and making minor modifications. Same general idea. I remember having read a discussion in the Web. The question was something like: How many times do you have to write a piece of code, before you create a function for it? I believe I still remember two answers: - One time. - Three times. The justification I can't remember, but what I would come up with now would be: (for "one time":) Functions structure your code. You don't have to wait for repetitions as an "excuse" to create them. (for "three times:) Relax. Don't overengineer. You need to have at least /three/ repetitions to be able to see a clear pattern. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: ANN: Version 0.5.1 of the Python config module has been released.
Many of those 4.8K "users" might be using indirectly via some other dependency - I'm not sure how GitHub calculates "used by", but even if it were a direct dependency, one has no idea if it's actually being used or not. so I tend not to worry about such things. My distlib library has only 2 stars, and is used by pip and therefore by many developers every day, and yet it doesn't merit a "used by" according to GitHub. I've had a few users contact me about the config library and they're happy with it and they find it useful, and that's good enough for me :-) On Sunday, 12 September 2021, 18:11:21 BST, Abdur-Rahmaan Janhangeer wrote: Used by 4.8k but only ... 4 stars -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 2021-09-12 10:28:22 -0700, [email protected] wrote: > On 2021-09-11 at 18:21:17 +0100, > Alan Gauld via Python-list wrote: > > On 11/09/2021 15:41, Peter J. Holzer wrote: > > > How is C's do/while loop more horrible than Pascal's repeat/until? [...] > > so code that has > > > > do{ > > code > > } > > while condition; > > > > Looks, for non-trivial cases, like a lot of code followed > > by an empty while loop. > > > > The do is easy to miss and the while loop disguised as > > a repeat termination is confusing. [...] > (Side question: why put the "{" next to the "do," but the "}" and the > "while" on separate lines?) > > And I would put the while on the same line as the closing brace (which > is also where I put the "else" in an if statement): > > do { > code; > } while(condition); Me too. I also checked two C books from "þe olde times" (K&R, 1st editiion, German translation; and "A Book on C" by Kelley/Pohl) and both nestle the while on the same line as the closing brace. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | [email protected] |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
RE: Friday Finking: Contorted loops
Some of what I read makes me chuckle.
Yes, large units of code, and even smaller ones, may be a chore to figure
out. Arguably harder when you use indentation and the next/last parts are
not even on the same screen as the rest. Sometimes you want to use a
split-screen in some editor to line up the two parts or some other
technique.
But my suggestion is to COMMENT things well and I mean too much!
do {
} while
Why not add a comment at the top like:
# The following loop has a WHILE clause controlling it at the end.
do { # until the while clause below
} while # End of the do loop.
My code tends to have brief comments especially when I have nested
constructs such as multiple nested loops or in sequence, or if statements
inside others. The comment often looks like
... # END of inner if
... # END of outer if
The point is that places where the way of writing a program may not be as
obvious as you want, may be the places you comment to make up for that.
Do people read the comments? Are they extra verbiage or in the way? Who
knows. And, of course, as I noted earlier, it is one more thing that gets in
the way.
There are languages which allow you to add some kind of labels in the code
and you can label a loop with something like "doo_wop:" and inside a nested
loop, you can break or continue to the named label and thus jump out
multiple levels if needed. The point is not to have that feature, but
perhaps have an option like:
do label {
code
} label while ...
Something that uniquely allows you to associate the end of the loop right
next to the end. Since the label can be anything allowed, it could by
something that suggest it is a while loop.
I appreciate programming environments that let you do complex, often nested,
things. But with great power can come great responsibility to use it well
and make sure others can figure it out.
-Original Message-
From: Python-list On
Behalf Of Peter J. Holzer
Sent: Sunday, September 12, 2021 4:49 PM
To: [email protected]
Subject: Re: Friday Finking: Contorted loops
On 2021-09-12 10:28:22 -0700, [email protected] wrote:
> On 2021-09-11 at 18:21:17 +0100,
> Alan Gauld via Python-list wrote:
> > On 11/09/2021 15:41, Peter J. Holzer wrote:
> > > How is C's do/while loop more horrible than Pascal's repeat/until?
[...]
> > so code that has
> >
> > do{
> > code
> > }
> > while condition;
> >
> > Looks, for non-trivial cases, like a lot of code followed by an
> > empty while loop.
> >
> > The do is easy to miss and the while loop disguised as a repeat
> > termination is confusing.
[...]
> (Side question: why put the "{" next to the "do," but the "}" and the
> "while" on separate lines?)
>
> And I would put the while on the same line as the closing brace (which
> is also where I put the "else" in an if statement):
>
> do {
> code;
> } while(condition);
Me too.
I also checked two C books from "þe olde times" (K&R, 1st editiion, German
translation; and "A Book on C" by Kelley/Pohl) and both nestle the while on
the same line as the closing brace.
hp
--
_ | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| | | [email protected] |-- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
--
https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 12/09/2021 09:11, jak wrote:
> if the only way to terminate a 'while True' loop is by using the 'break'
> statement, why is it allowed to add the 'else' statement which will only
> contain dead code?
>
> while True:
> break
> else:
> print('dead code')
>
Because to the interpreter the condition is not part of the
language. It is syntactically correct.
An optimiser OTOH might welkl determine that the condition
will never fail and therefore the else clause never be reached,
in which case it would remove the dead code (possibly emitting
a warning in the process?).
A linter likewise might identify the redundant code.
I don't use any python linters, does anyone know if they do
detect such dead spots?
--
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
--
https://mail.python.org/mailman/listinfo/python-list
