-1

I want to select from my function numbers_to_month and return the appropriate string (e.g. January). What is the best way to do this? I tried assigning a variable to numbers_to_month. e.g.

>>> test = numbers_to_months(1)
one

Hoever when I call that variable, i was expecting the appropriate month but i get an error. e.g.

>>> test()
Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    test()
TypeError: 'NoneType' object is not callable

My code:

def one():
    return "January"

def two():
    return "February"

def three():
    return "March"

def four():
    return "April"

def five():
    return "May"

def six():
    return "June"

def seven():
    return "July"

def eight():
    return "August"

def nine():
    return "September"

def ten():
    return "October"

def eleven():
    return "November"

def twelve():
    return "December"

def numbers_to_months(argument):
    switcher = {
        1: "one",
        2: "two",
        3: "three",
        4: "four",
        5: "five",
        6: "six",
        7: "seven",
        8: "eight",
        9: "nine",
        10: "ten",
        11: "eleven",
        12: "twelve"
        }
    # Get the function from the switcher dictionary
    func = switcher.get(argument, lambda: "Invalid Month")
    # Execute the function
    print(func)
ForceBru
  • 43,482
  • 10
  • 63
  • 98
rindel
  • 67
  • 2
  • 10
  • Use a dictionary: `monthnames = {"1":""January", "2":"February", ...}` - `print(monthnames[1])` - there is no need for any indirection. If it where you would need `"1": functionname_no_()_behind` .. and you would need to call it – Patrick Artner Feb 17 '19 at 16:21
  • 2
    `func` in `func = switcher.get(argument, lambda: "Invalid Month")` is not a function, but a string. `print(func)` doesn't execute the function, as your comment says; it just prints the `func` string. `numbers_to_months` also doesn't return anything, so `test` is `None`. – ForceBru Feb 17 '19 at 16:22
  • I am intentionally writing a switch instead of a dictionary. Correction on print(func) which is actually print(func()). but i get an error saying its not callable. – rindel Feb 17 '19 at 16:36
  • Yes, because it's the *string* (which happens to be the name of the function), not the *function*. Why doesn't the dictionary just hold the month names, which are *already strings*? – jonrsharpe Feb 17 '19 at 16:37

1 Answers1

1

Your dictionary needs to hold the function-names as variables not as "strings":

def one():    return "January"
def two():    return "February"
def three():  return "March" 
# snipp the remaining ones

def numbers_to_months(argument):
    # this indirection is not justified by any means, simply
    # map to the correct string directly instead of to a function
    # that returns the string if you call it...
    # you have to reference the function-name - not a string of it...
    switcher = { 1:  one, 2:  two, 3:  three, }

    # Get the function from the switcher dictionary
    func = switcher.get(argument)

    # return the result of _calling_ the func or default text
    return func() if func else "Invalid Month" 

for n in range(5):
    print(n, numbers_to_months(n)) 

0 Invalid Month
1 January
2 February
3 March
4 Invalid Month

You can do it even shorter:

def numbers_to_months(argument):
    def invalid(): 
        return "Invalid Month"

    switcher = { 1:  one, 2:  two, 3:  three, }
    return switcher.get(argument, invalid)() 

or

def numbers_to_months(argument):
    switcher = { 1:  one, 2:  two, 3:  three, }
    return switcher.get(argument, lambda: "Invalid Month")() 
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • thanks. always the obvious - i forgot to remove the "" in my dictionary. – rindel Feb 17 '19 at 19:23
  • @rin You might want to read https://stackoverflow.com/questions/6557553/get-month-name-from-number if you really deal with monthnames and this is not a simplified example – Patrick Artner Feb 17 '19 at 19:24