How to write a nested switch case in python? - python-3.x

Is that even possible?
What I know so far:
Python hasn't switch case but they have something called dictionary mapping.
def fun1():print("fun1")
def fun2():print("fun2")
def fun3():print("fun3")
def WannaBeSwitch(arg):
switch = {
0: fun1,
1: fun2,
2: fun3
}
return switch.get(arg, "blabla")
if __name__ == "__main__":
argument = 1
call_func = WannaBeSwitch(argument)
call_func()

I am working on the python project in which I needed to implement nested switch.
This answer helped me a lot.
Here is working example based on that answer. The example is how I implemented it in my project. You can make changes to fit it with your needs.
def fun1_1():print("fun1_1")
def fun1_2():print("fun1_2")
def fun1_3():print("fun1_3")
def fun1(sub_case):
sub_switch = {
1: fun1_1,
2: fun1_2,
3: fun1_3
}
sub_switch.get(sub_case, default_case)()
return
def fun2_1():print("fun2_1")
def fun2_2():print("fun2_2")
def fun2_3():print("fun2_3")
def fun2(sub_case):
sub_switch = {
1: fun2_1,
2: fun2_2,
3: fun2_3
}
sub_switch.get(sub_case, default_case)()
return
def fun3_1():print("fun3_1")
def fun3_2():print("fun3_2")
def fun3_3():print("fun3_3")
def fun3(sub_case):
sub_switch = {
1: fun3_1,
2: fun3_2,
3: fun3_3
}
sub_switch.get(sub_case, default_case)()
return
def default_case(): print("Unsupported case!")
main_switch = {
1: fun1,
2: fun2,
3: fun3
}
if __name__ == "__main__":
main_case = 2
sub_case = 3
main_switch.get(main_case)(sub_case)

I do not know what exactly you mean by nested switch case, but if I have gotten it right, there is no problem with using dictionary mapping inside the helpers functions. I mean something like this is possible, using your example as demonstration:
def fun1_1():print("fun1_1")
def fun1_2():print("fun1_2")
def fun1_3():print("fun1_3")
def fun1(arg):
switch = {
0: fun1_1,
1: fun1_2,
2: fun1_3
}
return switch.get(arg, "blabla")
def fun2_1():print("fun2_1")
def fun2_2():print("fun2_2")
def fun2_3():print("fun2_3")
def fun2(arg):
switch = {
0: fun2_1,
1: fun2_2,
2: fun2_3
}
return switch.get(arg, "blabla")
def fun3_1():print("fun3_1")
def fun3_2():print("fun3_2")
def fun3_3():print("fun3_3")
def fun3(arg):
switch = {
0: fun3_1,
1: fun3_2,
2: fun3_3
}
return switch.get(arg, "blabla")
def WannaBeSwitch(arg):
switch = {
0: fun1,
1: fun2,
2: fun3
}
return switch.get(arg, "blabla")
if __name__ == "__main__":
argument1 = 1
argument2 = 1
call_func = WannaBeSwitch(argument1)(argument2)
call_func()
Nevertheless, it does not look very readable... Maybe if you write what exactly do you want to do with it and how do you imagine you would use it, I could give you more helpful answer.

Related

How to push and pop to specific stacks(these are two list members within my Stack class) within a class?

Question from Chapter 3, CTCI - Write a program to sort a stack such that the smallest items are on the top. You can use an additional temporary stack, but you may not copy the elements into any other data structure. The stack supports the following operations: push, pop, peek, is_empty.
The solution given in the book is to loop through s and sort it by inserting each element from s in order into r, with the bigger elements on top. Once s becomes empty, copy over all elements from r to s.
But I am having trouble understanding how to push/pop on to the specific stacks(s or r) within my Stack class to implement this logic. Felt that the best way to do this was to pass the stack number into which the pushing/popping was to happen as arguments to the push, pop, peek, is_empty functions, but I am not sure if this is the best way. Also came across this answer but was not sure about it. I am a complete beginner to Object-Oriented programming using Python and I wanted to check if there was anything else I could do to make this better. This is what I have so far. My code seems to be error-prone, poorly written and any help would be appreciated. Thank you.
class Stack:
def __init__(self):
self.s = []
self.r = []
def is_empty(self, stknum):
if stknum == 1:
return self.s == []
elif stknum == 2:
return self.r == []
def peek(self, stknum):
if stknum == 1:
return self.s[-1]
elif stknum == 2:
return self.r[-1]
def push(self, item, stknum):
if stknum == 1:
self.s.append(item)
elif stknum == 2:
self.r.append(item)
def pop(self, stknum):
if stknum == 1:
return self.s.pop()
elif stknum == 2:
return self.r.pop()
def print_stack(self, stknum):
if stknum == 1:
return self.s
elif stknum == 2:
return self.r
To solve this, I created two separate classes, one for basic stack operations and the other to deal with the sorting logic. Then, created a stack object in main, pushed the elements into the stack and then passed my Stack class instance to the SortStack class.
stack = Stack()
stack.push(7)
stack.push(6)
stack.push(15)
stack.push(1)
print(stack.get_stack())
sort_obj = SortStack(stack)
sort_obj.sort_stack()
print(sort_obj.get_sorted_stack())
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def is_empty(self):
return self.items == []
def peek(self):
if not self.is_empty():
return self.items[-1]
def get_stack(self):
return self.items
class SortStack:
def __init__(self, stack_obj):
self.r = Stack()
self.s = stack_obj
def sort_stack(self):
while not self.s.is_empty():
tmp = self.s.pop()
while not self.r.is_empty() and self.r.peek() > tmp:
self.s.push(self.r.pop())
self.r.push(tmp)
while not self.r.is_empty():
self.s.push(self.r.pop())
def get_sorted_stack(self):
if not self.s.is_empty():
return self.s.get_stack()

Python Refactoring from Static class?

All over my code I use a python “static” class like this:
curStatus = StaticClass.getStat()
where
class StaticClass:
#staticmethod
def getStat () -> str:
return "noSimulate"
But now I have a refactor issue where sometimes SIMULATE is TRUE or FALSE
SIMULATE: bool = false
If Simulate is true, I want staticmethod.getStat() to be a different method.
But I only want to check SIMULATE once and use polymorphism to do the rest.
& I don’t want to refactor the whole code base.
How can I change StaticClass method by just checking SIMULATE once?
I used this info: python3-patterns
and created these two .py files:
Testing.polymorphism
# https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Factory.html
SIMULATE:bool = True
# class myBase(object):
class myBase:
#staticmethod
def factory(sim:bool) :
return yesSim() if sim else myBase()
#staticmethod
def getDroneStatus() -> str:
print("myBase.getDroneStatus()")
return "UNITIALIZED! FAIL!!"
#staticmethod
def getStaticStatus() -> str:
print("myBase.getStaticStatus()")
return "UNITIALIZED! FAIL!!"
class yesSim(myBase):
#staticmethod
def getDroneStatus() -> str:
return "yesSim"
GSCRAMtcp = myBase.factory(SIMULATE)
if __name__ == '__main__':
myTCP = myBase.factory(SIMULATE)
print(myTCP.getStaticStatus())
print(myTCP.getDroneStatus())
and this testfile:
from Testing.polymorphism.testPolymorph import GSCRAMtcp
if __name__ == '__main__':
print(GSCRAMtcp.getDroneStatus())
print(GSCRAMtcp.getStaticStatus())

Python TypeError object() takes no parameters while class

class Tank(object):
def _init_(self,name):
self.name = name
self.alive = True
self.ammo = 5
self.armor = 60
def _str_(self):
if self.alive:
return "%s (%i armor and %i shells left)"%(self.name,self.armor,self.ammo)
else:
return "%s is DEAD !" % self.name
def fire_at(self,enemy):
if self.ammo >= 1:
self.ammo-=1
print(self.name," fires on ",enemy.name)
enemy.hit()
else:
print(self.name," has no shells!")
def hit(Self):
self.armor-=20
print(self.name," is hit !")
if self.armor<=0:
self.explode()
def explode(self):
self.alive = False
print(self.name," explodes !!!!")
from tank import Tank
tanks = {"a":Tank("Alice"), "b":Tank("Bob"), "c":Tank("Crane") }
alive_tanks = len(tanks)
while alive_tanks > 1:
print()
for tank_name in sorted(tanks):
print(tank_name,tanks[tank_name])
first = raw_input("Who fires ?").lower()
second = raw_input("Who at ?").lower()
try:
first_tank = tanks[first]
second_tank = tanks[second]
except KeyError:
print("No such Tank ")
continue
if not first_tank.alive or not second_tank.alive:
print("One of those is dead!")
continue
print()
print("*"*30)
first_tank.fire_at(second_tank)
if not second_tank.alive:
alive_tanks -= 1
print("*"*30)
for tank in tanks.value():
if tank.alive:
print(tank.name," is the winner !")
break
On running it gives error :
tanks = {"a":Tank("Alice"), "b":Tank("Bob"), "c":Tank("Crane") }
TypeError: object() takes no parameters
What I need to resolve it?
class init methods are ddunder methods, you need to declare the init method with two underscores before and after, if not the the default init method is called.
__init__(self, name)
instead of
_init_(self, name)
Same goes for your str method, it needs to be:
__str__

Python 3.5 class variables

I'm new to python, and I'm using python 3.5 on Ubuntu. I did some research about this question and i found a lot of answers. What I'm doing looks like what everyone is saying I'm supposed to do, but I'm still receiving errors.
import csv
import sys
Class State():
started = False
def waiting(self):
self.started
if self.started == False:
self.started = True
return
def buy_in(self, col):
if self.started == False:
return
else:
print(col)
def read_file(file):
csv_list = csv.reader(file)
header = True
for row in csv_list:
if header:
header = False
continue
col = float(row[5])
if col < 0 :
State.waiting()
if col >= 0:
State.buy_in(col)
file.close()
def main(filename):
file = open(filename)
read_file(file)
def __name__ == '__main__':
main(sys.argv[1])
I'm just trying to create a pseudo FSM in python, by using a class and methods. I just need to create a global bool. I don't really understand what I'm doing wrong. IF someone doesn't mind giving me some clarity, I would appreciate it. Thanks
To clarify, I'm getting the NameError on the if statement in the buy_in method.
Try:
class State():
started = False
def waiting(self):
if self.started == False:
self.started = True
return
def buy_in(self, col):
if self.started == False:
return
else:
print(col)
Since started is a class variable you need to use self. when calling it. It is not a global variable so you do not need the global call. Each of the methods inside of the class also needs self as an argument.

How do i make a unittest ? what does it look like?

def abn_abc(voteslist):
sums = {}
for vote in votes:
if vote in sums:
sums[vote] += 1
else:
sums[vote] = 1
return tally_ballots(sums)
How do I write a unit test for this function?
Something like this:
import unittest
from wherever import abn_abc
class AbnAbcTest(unittest.TestCase):
def test_abn_abc(self):
list_for_testing with = [<insert list here>]
self.assertEqual(abn_abc(list_for_testing_with), <expected result>)
if __name__ == '__main__':
unittest.main()
Here's the documentation.

Resources