Python Forum
[split] Creating a variable as a function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[split] Creating a variable as a function
#1
Hi,

I knew dict could be used to replace "select... case"... statements, the single biggest thing i missed in Python.
So with the info of post #5, i tried to make something, but it's not quite allright. What is wrong? I get an extra 'None' in the output.
Output:
This has plenty of useful applications, e.g. the pythonic way to create a menu/switch statement, using dict with functions as values.
def AAA():
    print('AAAxxx')

def BBB():
    print('BBByyy')

def CCC():
    print('CCCzzz')

aaa = AAA
bbb = BBB
ccc = CCC

myDict = {100:aaa,200:bbb,300:ccc}
x = myDict[200]()
print(x)
Can i do without line 15 ?
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#2
(Sep-06-2020, 06:55 AM)DPaul Wrote: I get an extra 'None' in the output.

Of course you do. On line 15, you assign the return value of the function to x. The function referred to by bbb (and in fact this is true for all your functions) has no return statement, therefore implicitly returns None to its caller.
Reply
#3
(Sep-06-2020, 07:04 AM)ndc85430 Wrote:
(Sep-06-2020, 06:55 AM)DPaul Wrote: I get an extra 'None' in the output.

Of course you do. On line 15, you assign the return value of the function to x. The function referred to by bbb (and in fact this is true for all your functions) has no return statement, therefore implicitly returns None to its caller.
OK, is this "perfect" then ? :-)
def AAA():
    return 'AAAxxx'

def BBB():
    return 'BBByyy'

def CCC():
    return 'CCCzzz'

aaa = AAA
bbb = BBB
ccc = CCC

myDict = {100:aaa,200:bbb,300:ccc}

x = myDict[200]()
print(x)
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#4
Your example is quite contrived, but in general, this is better design yes. In a real example, these functions would do more complex things and separating the concern of printing from what their main job is would make them more reusable, easier to test and maintain.
Reply
#5
(Sep-06-2020, 07:24 AM)ndc85430 Wrote: In a real example, these functions would do more complex things and separating the concern of printing from what their main job is would make them more reusable, easier to test and maintain.
Agreed.

This is a step closer to "select..." statements of old. Smile

What i am still missing is "select" equivalents for:

x is between a and b.. do function...
x is between c and d ... do function...
or even,
x is a,b,c or d ... do function ....
x is w,z,t or v ... do function ...

Any thoughts on that?

paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#6
Besides cascading if statements?
import random

def fnA():
    return 'A'

def fnB():
    return 'B'

def fnC():
    return 'C'

selector = random.random()
if selector < 0.333 :
    print(fnA())
elif selector >= 0.333 and selector < 0.7 :
    print(fnB())
else :
    print(fnC())
Reply
#7
(Sep-06-2020, 11:52 AM)jefsummers Wrote: Besides cascading if statements?

Cascading if statements have always been a possibility, since times immemorial, if you have just a couple of "cases".
But if you need 10, 50 or more, it becomes (very) cumbesome.

I've looked into this, and as long as a dict key MUST be a single item, dicts are not a solution.
I've seen some propose a tuple range as key, but it does not produce the goods.

It seems strange that python does not provide some direct construct for those very common "cases".

Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#8
you can do something like this
def spam():
    return 'spam'

def eggs():
    return 'eggs'

# option 1: expand the keys
menu = {('a', 'b', 'c'):spam, ('x', 'y', 'z'):eggs}
menu = {key:value for item, value in menu.items() for key in item}
print(menu['a']())
print(menu['z']())

# option 2: define helper function
menu = {('a', 'b', 'c'):spam, ('x', 'y', 'z'):eggs}
def lookup_in(lookup_key, menu):
    for key, value in menu.items():
        if lookup_key in key:
            return value
print(lookup_in('a', menu)())
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
OK, I had seen attempts to do a tuple 'range' as key, post #8 proposes a kind of tuple 'list'.
In the old days we called this a "workaround". :-)

So we have a select...case solution with dictionaries for:
- Individual keys, the most direct solution (post # 3)
- tuple lists (post # 8)

Still one down : the "between" or "range" case.

Thanks,
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#10
(Sep-06-2020, 02:22 PM)DPaul Wrote: Still one down : the "between" or "range" case.
it will be the same workaround like the tuple
def spam():
    return 'spam'
 
def eggs():
    return 'eggs'

menu = {(2, 5):spam, (8, 10):eggs}
def lookup(lookup_key, menu):
    for (start, end), value in menu.items():
        if start <= lookup_key <= end:
            return value
print(lookup(9, menu)())
Here the tricky part is handling overlapping keys

(Sep-06-2020, 02:22 PM)DPaul Wrote: a kind of tuple 'list'.
no, it's not kind of tuple list, it's a tuple
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable for the value element in the index function?? Learner1 8 641 Jan-20-2024, 09:20 PM
Last Post: Learner1
  Variable is not defined error when trying to use my custom function code fnafgamer239 4 585 Nov-23-2023, 02:53 PM
Last Post: rob101
  Printing the variable from defined function jws 7 1,295 Sep-03-2023, 03:22 PM
Last Post: deanhystad
  Function parameter not writing to variable Karp 5 944 Aug-07-2023, 05:58 PM
Last Post: Karp
  Split string using variable found in a list japo85 2 1,300 Jul-11-2022, 08:52 AM
Last Post: japo85
  Retrieve variable from function labgoggles 2 1,045 Jul-01-2022, 07:23 PM
Last Post: labgoggles
  Cant transfer a variable onto another function KEIKAS 5 1,892 Feb-09-2022, 10:17 PM
Last Post: deanhystad
  Please explain uncommon way of declaring and using variable [function.variable] esphi 4 2,333 Nov-07-2020, 08:59 AM
Last Post: buran
  Spyder Quirk? global variable does not increment when function called in console rrace001 1 2,224 Sep-18-2020, 02:50 PM
Last Post: deanhystad
  passing variable to function Rejoice 4 2,875 Sep-11-2020, 03:27 AM
Last Post: Pleiades

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020