Re: Switch function

2019-02-03 Thread Dan Sommers

On 2/3/19 9:03 PM, Avi Gross wrote:

> The example I show above could in many cases be done as you describe
> but what are you gaining?
>
> I mean if I subtract the integer representation of a keyboard
> alphabetic letter (ASCII for the example) from letter 'a' or 'A' then
> A maps to 0 and B maps to 1 and ...  Z maps to 26. So, you could make
> a list of 26 functions (some may be absent) and your entire switch
> statement looks like:
>
>funcs=[zeroeth,first,other,...,last] # list of function handles
>var=input("Enter a Command: ")
>if ord('A') <= ord(var[0]) <= ord('Z'):
>result = funcs[ord(var[0]) - ord('A')]()
>
> Is that short enough?

It's not a matter of shortness.  Your code encapsulates the idea of
dispatching to a 0-airity function based on an input.  In Python,
though, I'd still use a dictionary, which would be more flexible (what
if I start to use digits or other characters as commands?)  and less
error prone.

> Your comment about object polymorphism is interesting. I am picturing
> how each choice somehow delivers an object that automatically is set
> up to do the right thing.

Disclaimer:  I speak OO as a second language, and only when there is an
obvious and compelling advantage over some other paradigm.  That said:

If the mapping from input to function is more complex than A -> func1, B
-> func2, etc., then a factory function that builds an object with an
execute method is a good way of isolating the mapping and keeping the
main code clean and clear.

> Again, see how can you write a COMPLICATED try command that captures
> many things including real errors?

Don't do that.  Why are you writing COMPLICATED try commands?

Did you have a Python question?  ;-)
--
https://mail.python.org/mailman/listinfo/python-list


RE: Switch function

2019-02-03 Thread Avi Gross
Dan,

I agree and have felt no need to do a method like this. Most of the time a
switch is easy to avoid or even forget that it exists.  I rarely needed to
use these years ago when they were available in C and C++ , JAVA,
JavaScript, PERL  or R or under  other *names* but similar functionality
like COND in versions of LISP or CASE in PASCAL.

The times I would use it would not be when were a relatively few cases. It
makes more sense for example when you are accepting a one-character command
in the very old style from the user. I repeat, OLD style. Your main loop may
largely consist of a switch statement where every possible keystroke calls
one of a set of functions. I mean things like D is for Delete and I is for
insert and A is for Append and Q is for QUIT and some are absolutely not
mnemonic like V is for Paste.

I have read books that suggest having a long function is a sign of clutter
or even insanity and I feel that is not realistic in many cases. 

The example I show above could in many cases be done as you describe but
what are you gaining?

I mean if I subtract the integer representation of a keyboard alphabetic
letter (ASCII for the example) from letter 'a' or 'A' then A maps to 0 and B
maps to 1 and ...  Z maps to 26. So, you could make a list of 26 functions
(some may be absent) and your entire switch statement looks like:

funcs=[zeroeth,first,other,...,last] # list of function handles
var=input("Enter a Command: ")
if ord('A') <= ord(var[0]) <= ord('Z'):
result = funcs[ord(var[0]) - ord('A')]()

Is that short enough?

Mind you, that is not the same as a switch statement form that allows
arbitrary code after each choice and lets you access variables at that level
and change them, as well as call functions with specific arguments that make
sense at that time. Yes, judicious use of the global or nonlocal statement
can dangerously get you some of that functionality.

A reasonable goal might be to have the code at each case be relatively
brief. Maybe a few lines adjusting local variables then calling a function
that lets more code be elsewhere by passing in additional things needed in
that context or passing in mutable arguments. The indentation should make it
reasonable to follow as if you are looking at N different functions where
each one is not too large even if it is all in one large switch.

Now this sounds quite a bit like the dictionary trick but note many of the
above languages do not have a built-in dictionary concept and some may not
support lists of functions or objects. I have seen monstrosities like this:

functionTop is:
If var == 'A':
# do something
else:
functionB(var)

Guess what functionB says?

Yep, if it is 'B" do something else call functionC.

So a mere 26 functions, each short and stacked. Ugh!

It may be a matter of taste and I have seen places such as statistical
calculations where such an approach is even needed. In very brief, some
tests require a choice of TWO so one choice is A versus non-A and then you
do something with the non-A that are B versus non-B.

Your comment about object polymorphism is interesting. I am picturing how
each choice somehow delivers an object that automatically is set up to do
the right thing.

Having said that, I realize how there is something in python quite similar
to a case statement!

Picture my example where you have a try statement that raises at least 26
error objects followed by up to 26 catch statements:

try:
something that raises a designer exception
catch errorA as var: pass
catch errorb, errorB: pass
...
catch errorZ: pass

That looks like a switch in many ways and lets you combine multiple choices
into one case. Heck, there is also a finally and else clause you can use for
fine tuning as in setting a default.

Again, see how can you write a COMPLICATED try command that captures many
things including real errors?

I know I keep repeating this but experience tells me that if not mentioned,
someone will make believe I meant something other than what I say. The above
is NOT a suggestion of what to do. It is an example of another feature that
IS in the language that in some ways is much like the switch statement. Not
always a good idea to abuse it when it can be done with IF variants or a
dict jump or many other gimmicks.

In the above the  *raise* statement within whatever you try can do the same
trick as before and create a small integer offset from letter 'A' to use in
making a slightly different object for each case in one of many ways. I will
stop here.


-Original Message-
From: Python-list  On
Behalf Of Dan Sommers
Sent: Sunday, February 3, 2019 8:29 PM
To: python-list@python.org
Subject: Re: Switch function

On 2/3/19 5:40 PM, Avi Gross wrote:

> Bottom line, does anyone bother u

Re: Switch function

2019-02-03 Thread Dan Sommers

On 2/3/19 5:40 PM, Avi Gross wrote:


Bottom line, does anyone bother using anything like this? It is actually a
bunch of hidden IF statements matched in order but may meet many needs.


I sure don't.  In the rare case that I might use a switch
statement in another language, I just use a series of elifs,
or maybe a dictionary I build once and use over and over (a
habit left over from the old days of extremely constrained
systems, when medium-to-large lookup tables and simple logic
was better than many kinds of runtime computation).

If it gets unweidly, I think harder about how to isolate the
"switching" from the results, and usually end up with a
collection of smaller functions to do the work, or high order
functions, or maybe some sort of object oriented polymorphism
as a last resort.
--
https://mail.python.org/mailman/listinfo/python-list