I have a little Python program that uses keyboard input to run certain commands.
I setup everything in one main program loop but now I'm wondering, do I even need a main loop?
Here is what I mean:
mainProgramLoop = 1
while mainProgramLoop == 1:
print ("\nType in the command. ")
keyBoardInput= input("command:")
if keyBoardInput == "a":
#do this
elif keyBoardInput == "b":
#do this
Do I actually need that while loop?
Thanks!
No, you do not need a main loop if you use the cmd.Cmd class included with Python:
#! /usr/bin/env python3
import cmd
class App(cmd.Cmd):
prompt = 'Type in a command: '
def do_a(self, arg):
print('I am doing whatever action "a" is.')
def do_b(self, arg):
print('I am doing whatever action "b" is.')
if __name__ == '__main__':
App().cmdloop()
The documentation for the cmd module includes an example near the bottom to help get you started.
Related
Hello everyone im fairly new to python and this is my first language im learning so far. Im making a menu using a while true loop that takes input to select whichever flashing method a person needs to use and after calling whatever file using subprocess.popen or subprocess.call and it finishes it goes back into the menu loop but does not respond to any input at all.
import sys
import time
import subprocess
#!/bin/bash
sys.path.append
menu = True
def mainMenu():
while menu:
print("""
##################
# Utilities Menu #
##################
1. Tray Flasher
2. ESP Burner
3. Quit
""")
choice = (input('Select a utility: '))
if choice == '1':
trayFlasher()
elif choice == '2':
espBurner()
elif choice == '3':
print('Goodbye!')
def trayFlasher():
print('Have Fun!')
time.sleep(1)
subprocess.call(["<path to file>"])
def espBurner():
print('Burn Baby Burn...')
time.sleep(1)
subprocess.Popen(['<path to file>'])
sorry if my code is not so good or efficient, currently still learning. TIA!
I'm trying to make a dead-simple bot according to this video: https://www.youtube.com/watch?v=5Jwd69MRYwg
The main function that is supposed to be called when a part of the screen changes color simply is not being run at all.
I've tried ending the program with
"main()"
and
"if __name__ == '__main__':
main()"
respectively. Neither have allowed the code to run
def restart_game():
time.sleep(1)
pyautogui.click(Coordinates.replayBtn)
def image_grab():
box = (290, 465, 305, 487)
image = image_grab_lib.grab(box)
grey = ImageOps.grayscale(image)
a = array(grey.getcolors())
print(a.sum())
return a.sum()
def main():
restart_game()
print("blip")
if image_grab() != 577:
print("Jump")
press_space()
time.sleep(1)
restart_game()
if __name__ == '__main__':
main()
I expect the main function to run and give print "blip" and "jump", currently running all the other code and entirely skipping the main function.
shows what the warning looks like in PyCharm - image
Your code is unreachable because you have an infinite while loop before main() definition. It's a good practice in applications that require while loop to put it inside if name == 'main' condition after all variables are declared.
Like this:
if __name__ == '__main__':
while True:
do_something()
I'm trying to write code that create sub-process using another module(demo_2.py),
and exit program if i get wanted value on sub-processes.
But result looks like this.
It seems that demo_1 makes two sub-process that run demo_1 and load demo_2.
I want to make sub-process only runs demo_2.
What did i missed?
demo_1.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from multiprocessing import Process,Queue
import sys
import demo_2 as A
def multi_process():
print ("Function multi_process called!")
process_status_A = Queue()
process_status_B = Queue()
A_Process = Process(target = A.process_A, args = (process_status_A,))
B_Process = Process(target = A.process_A, args = (process_status_B,))
A_Process.start()
B_Process.start()
while True:
process_status_output_A = process_status_A.get()
process_status_output_B = process_status_B.get()
if process_status_output_A == 'exit' and process_status_output_B == 'exit':
print ("Success!")
break
process_status_A.close()
process_status_B.close()
A_Process.join()
B_Process.join()
sys.exit()
print ("demo_1 started")
if __name__ == "__main__":
multi_process()
demo_2.py
class process_A(object):
def __init__(self, process_status):
print ("demo_2 called!")
process_status.put('exit')
def call_exit(self):
pass
if process_status_A == 'exit' and process_status_B == 'exit':
should be
if process_status_A_output == 'exit' and process_status_B_output == 'exit':
Conclusion: The naming of variables is important.
Avoid long variable names which are almost the same (such as process_status_A and process_status_A_output).
Placing the distinguishing part of the variable name first helps clarify the meaning of the variable.
So instead of
process_status_A_output
process_status_B_output
perhaps use
output_A
output_B
Because Windows lacks os.fork,
on Windows every time a new subprocess is spawned, a new Python interpreter is started and the calling module is imported.
Therefore, code that you do not wish to be run in the spawned subprocess must be "protected" inside the if-statement (see in particular the section entitled "Safe importing of main module"):
Thus use
if __name__ == "__main__":
print ("demo_1 started")
multi_process()
to avoid printing the extra "demo_1 started" messages.
I would like to type "c" in my commandline, hit enter and have it run the "command" command. This code does what I want, but it does not use cmd. I would like to use cmd:
import sys
def command():
print("This is a command")
def quit():
print("goodbye")
sys.exit()
def take(item=None):
if item:
print("You take %s" % item)
else:
print("What would you like to take?")
commands = {
'command': command,
'quit': quit,
'take': take,
}
def complete(text, state):
print("Here is the text: %s and here is the state %s" % (text, state))
def my_loop():
while True:
c = raw_input("\n>")
if c.strip():
c = c.split(' ', 1)
for command in commands:
if command.startswith(c[0]):c[0] = command
func = commands.get(c[0], None)
if func:
if len(c) == 1:func()
else:func(c[1])
else:print("I don't understand that command")
my_loop()
Here is the same using cmd, but it does not run the "command" command when I type "c" and hit enter.
import sys, cmd
class Mcmd(cmd.Cmd):
prompt = '\n>'
def default(self, arg):
print("I do not understand that command. Type 'help' for a list of commands")
def do_command(self, line):
print("This is a command")
def do_quit(self, arg):
print("See you")
return True
Mcmd().cmdloop()
How can I get the start of the command to trigger the "command" or "quit" command using cmd?
("c", "co", "com", "comm"...)
all trigger the "command" function.
I was considering using the new textwrap module, but textwrap has problems being cross-platform.
Is there any other way to do this?
thank you,
You already managed to figure out how to override the default method, so you can extend that to look up a compatible method from within your Mcmd class. Try something like this:
def default(self, line):
command, arg, line = self.parseline(line)
func = [getattr(self, n) for n in self.get_names()
if n.startswith('do_' + command)]
if len(func) == 1:
return func[0](arg)
print("I do not understand that command. Type 'help' for a list of commands")
Running that
>a
I do not understand that command. Type 'help' for a list of commands
>c
This is a command
>ca
I do not understand that command. Type 'help' for a list of commands
>co
This is a command
>q
See you
While technically a duplicate of Aliases for commands with Python cmd module the answer isn't quite complete; it doesn't properly address ambiguous cases (say you got both do_command and do_copy, what should happen on the input of c and co?). Here it only returns if there is a singular match.
Alternatively Python cmd module command aliases is a possible answer, but it's just tedious.
So say I have this graph
class Graph:
def __init__(self):
self.nodes =[]
self.edges = {}
def add_node(self,value):
self.nodes.append(value)
def is_node_present(self,node):
return True if node in self.nodes else False
Now what I want to do is something have user interact with this class..
Something like:
> g = Graph()
query executed
> g.add_node(2)
query executed
>g.is_node_present(2)
True
You know something like this.. (until user presses some secret button to quit)
How do i do this in python
Thanks
You want to look at http://docs.python.org/2/library/cmd.html as it handles the processing loop etc.
Dough Hellman http://www.doughellmann.com/PyMOTW/cmd/ is always a great resource of examples.
From Dough
import cmd
class HelloWorld(cmd.Cmd):
"""Simple command processor example."""
def do_greet(self, person):
"""greet [person]
Greet the named person"""
if person:
print "hi,", person
else:
print 'hi'
def do_EOF(self, line):
return True
def postloop(self):
print
if __name__ == '__main__':
HelloWorld().cmdloop()
Example
$ python cmd_arguments.py
(Cmd) help
Documented commands (type help ):
========================================
greet
Undocumented commands:
======================
EOF help
(Cmd) help greet
greet [person]
Greet the named person
Again all from Dough Hellman :D
You can do this with raw_input()
To quit you have to press Crtl+C
A small sample script:
import readline # allows use of arrow keys (up/down) in raw_input()
# Main function
def main():
# endless command loop
while True:
try:
command = raw_input('$ ')
except KeyboardInterrupt:
print # end programm with new line
exit()
parseCommand(command)
def parseCommand(command):
print 'not implemented yet'
if (__name__ == '__main__'):
main()
Very simple python shell-like environment using exec:
cmd = raw_input("> ")
while cmd:
try:
exec(cmd)
except Exception, e:
print str(e)
cmd = raw_input("> ")
As a side note, using exec is dangerous, and should be executed only by trusted users. This allows users to run any command they wish on your system.