Recently I started a project. My goal was it to have a script, which, once launched, could be able to control actions on the hosts computer if an instruction was send via email. (I wanted this so I could start tasks which take a long time to complete while I'm away from home)
I started programming and not long after I could send emails, recieve emails and analyze their content and take actions responding to the content in the email. The way I did it was like this: I first tried to use commands without a prefix but this caused errors so i added and "!" infront of every command which could be taken. Then I would split the contents of the email whenever there was a new line.
contents_of_the_email ="!screen\n!wait 5\n!hotkey alt tab\n"
# takes a screenshot waits 5 seconds and presses alt tab
lines = contents_of_the_email.count("\n")
contents_of_the_email = contents_of_the_email.split("\n")
for i in range(lines):
if "!screen" in contents_of_the_email[i]:
print("I took a screenshot and sent it to the specified email!")
elif "!wait " in contents_of_the_email[i]:
real = contents_of_the_email[i].split("!wait ")
print(f"I slept for {real[1]} seconds!")
elif "!hotkey " in contents_of_the_email[i]:
real = contents_of_the_email[i].split(" ")
print(f"I pressed the keys {real[1]} and {real[2]} at the same time!")
I replaced the actual code of the commands with print statements as they are not needed to understand my problem or recreate it.
Now this was getting very messy. I had added around 20 commands and they started conflicting. I mostly fixed it by changing the names of the commands but it was still spaghetti code.
I want to know if there is a more elegant way of adding commands to my program, I would desire something that works like this:
def takeScreenshot():
print("I took a screenshot!")
addNewCommand(trigger="!screen",callback=takeScreenshot())
If this is possible in python I would really appreciate to know! Thank you :D
CodePudding user response:
You can try something like this:
def take_screenshot():
print("I took a screenshot!")
def wait(sec):
print(f"I waited for {sec} secs")
def hotkey(*args):
print(f"I pressed the keys {', '.join(args)} at the same time")
def no_operation():
print("Nothing")
FUNCTIONS = {
'!wait': wait,
'!screen': take_screenshot,
'!hotkey': hotkey,
'': no_operation
}
def call_command(command):
function, *args = command.split(' ')
FUNCTIONS[function](*args)
contents_of_the_email = "!screen\n!wait 5\n!hotkey alt tab\n"
# takes a screenshot waits 5 seconds and presses alt tab
for line in contents_of_the_email.split("\n"):
call_command(line)
Just move funtions and dict definition to separate module.
CodePudding user response:
Have you considered using dictionaries to call your functions?
def run_A():
print("A")
# code...
def run_B():
print("B")
# code...
def run_C():
print("C")
# code...
inputDict = {'a': run_A, 'b': run_B, 'c': run_C}
# After running the above
>>> inputDict['a']()
A
CodePudding user response:
Try using the built-in module cmd:
import cmd, time
class ComputerControl(cmd.Cmd):
def do_screen(self, arg):
pass # Screenshot
def do_wait(self, length):
time.sleep(float(length))
def do_hotkey(self, arg):
...
inst = ComputerControl()
for line in contents_of_the_email.splitlines():
line = line.lstrip("!") # Remove the '!'
inst.onecmd(line)