0

I am trying to implement the switch in Dictionary in Python. But when I call the method
chooices.get(x, "Ther is no program") It call all the Function in the statment rather than calling x function.

I have read this implementation Replacements for switch statement in Python?

but it was not helpful in my case as my function has print statement

Main file contain the code

from  Day1.Day1 import Day1
from Day2.TipCalculator import TipCalculator


def choose():
    print("Choose From the following Program:\n")
    day1 = Day1()
    day1.day1()

    day2 = TipCalculator()
    day2.day2()


    x = int(input());


    chooices={
        1: day1.program1(),
        2: day2.program1(),

    }
    chooices.get(x, "Ther is no program")    

choose()

Day1 Class contain code

class Day1:

    def day1(self):
        print('1. Band name Generator\n')

    def program1(self):
        print('Welcome to Band Name Generator.\n')
        cityName=input('What\'s is the name of city you grew up?\n')
        petName = input('What\'s your pet\'s name?\n')
        print('Your Band Name could be : '+cityName+" "+petName)

Class Tip Calculator Code

class TipCalculator:
    def day2(self):
        print("2. Tip Calculator For  Bill.\n")

    def program1(self):
        print('Welcome to tip calculator.\n')

I just need the implementation Of switch statement which call Requested Program just like switch. I know Its possible through If-else but Dictionary mapping seems too be good alternative of switch

  • 1
    I ran the code and the switcher worked correctly. A function is an object. The function is invoked with you add () telling the interpretor to execute the function. – Golden Lion Nov 05 '20 at 23:29
  • Is this code working correctly? I try but it work strangely. If x=2, it will still call the 1: day1.program1() than 2: day2.program1(), instead of calling only 2:day2.program1(), I am using pycharm ide – Sardar Badar Saghir Nov 06 '20 at 17:58
  • 1
    I discovered the code dilemma for the expected output. study closures. The code uses closures to store the values of cityName+" "+petName. You have two classes day1 and day2 that call their method function1 however the interpretor creates a closure for the global function cityName and petName. print(cell.cell_contents for cell in program1.__closure__]) – Golden Lion Nov 06 '20 at 23:52
  • Issue has been resolved the error was that i was using day1.day() instead of day1.day – Sardar Badar Saghir Nov 07 '20 at 15:57
  • vote up my explanation of closures – Golden Lion Nov 08 '20 at 22:44

3 Answers3

1

Overview: the interpretor creates a closure for the variables that the child function uses that are non local. In this example the child variable, value is 22 and stored in the closure cell.

  def parent(arg_1, arg_2):
  value=22
  my_dict = {'chocolate':'yummy'}
  def child():
    print(2*value)
    print(my['chocolate'])
    print(arg_1 + arg_2)
   return child

  new_function=parent(3,4)

  print(cell.cell_contents for cell in new_function.__closure__])
Golden Lion
  • 3,840
  • 2
  • 26
  • 35
1

If you don't have a lot of variants, the if/elif/else statements can be streamlined using a helper function for the switch. This is only syntactic candy but it may be sufficient for small value sets.

def switch(v): yield lambda *c: v in c

Example usage:

x = int(input())
for case in switch(x):
    if   case(1): day1.program1()
    elif case(2): day2.program1()
    else:         print("there is no program")

supporting multiple values for the same method call:

x = int(input())
for case in switch(x):
    if   case(1,5):   day1.program1()
    elif case(2,3,4): day2.program1()
    else:             print("there is no program")

you can also use it in a more C-like style

x = int(input())
for case in switch(x):

    if case(1,5):   
       day1.program1()
       break

    if case(2,3,4): 
       day2.program1()
       break
else:
    print("there is no program")
Alain T.
  • 40,517
  • 4
  • 31
  • 51
1

If you have python 3.10 or higher, a proper switch analogue was implmemented called "match" which should work quite well in replacing any nested if statments the other answers may have.

If you dont have 3.10, and you are okay with a pretty hacky solution, mine uses the ideas from withhacks (specifically from AnonymousBlocksInPython). I have recently created my own version of a switch statment in python that acts more like how i am used to in C#. You can expand this as much as you want, way past single line arguments or assignments.

It uses context managers so that you can treat each case as its own code block with indentation and all. It will never enter the cases if the case value does not match the switch value so for code that is extremely system taxing, you can be sure it is not running code that does not need to be.

import sys


class CaseReturn(Exception):pass
class Case:
    def __init__(self, caseVal): self._caseVal_ = caseVal
    def _trace_(self,frame,event,arg): raise CaseReturn
    def __enter__(self):
        if self._caseVal_ == Switch._singleton_._switch_: return
        sys.settrace(lambda *args, **keys: None)
        sys._getframe(1).f_trace= self._trace_
    def __exit__(self,ExType,ExVal,ExTrace): 
        if ExType is None: raise CaseReturn
        return ExType is CaseReturn 


class Switch:
    _singleton_:'Switch' = None
    def __init__(self, switchVal,Default=None): self._switch_ = switchVal
    def __enter__(self):Switch._singleton_ = self
    def __exit__(self,ExType,ExVal,ExTrace): 
        Switch._singleton_ = None
        return ExType is CaseReturn


with Switch(2):
    with Case(1): 
        print('This should not make it')
    with Case(2):
        print('I made it')
    with Case(3):
        print('This should never be called')

You can easily extend this out to check multiple cases by just changing the caseVal to a list and doing if Switch._singleton_._switch_ in self._caseVal_:

One caveat is, you cannot make the Case statments one-liners like:

Case(0): print('I am one line')

That will not work and end up calling the code in that case no matter what. I hope this is useful to you or anyone who is searching for custom Switch statments!

ZXYNINE
  • 712
  • 4
  • 5