Reputation: 17
I am making a virtual terminal for a basic hacking game. Commands need to be given by user. Commands are stored as a dictionary, like the following
commandslist = {"systemtime": systemtime(),
"ping": ping(),
"pwd": pwd(),
"ifconfig": ifconfig(),
"help": helpmenu(),
"shop": shop()}
That references the actual functions
def ifconfig():
ipaddr = user["ipaddr"]
return ipaddr
def ping(ip4="127.0.0.1"):
if ip4 in enemyuser["ipaddr"]:
x = "64 bytes from " + ip4 +": icmp_seq=1"
else:
x ="No ping response"
return x
The code in main.py reads for user input and for loops to find it. I dont want a bunch of messy if statements
while 1:
userinput = input(bash)
if " " in userinput:
command, options = userinput.split(" ")
else:
command = userinput
for i in commandslist:
if i == command:
print(commandslist[i])
Basically I need to pass the ip address of enemy computer to the ping command but I can't figure out a way if I could update the ping() call in the dictionary to include the options that would be good
Upvotes: 0
Views: 47
Reputation: 45736
First, this isn't directly the problem you're asking about, but {"systemtime": systemtime()}
calls the systemtime
function when the dictionary is created, not when the "systemtime"
key is accessed! This means all your functions will run immediately at the start, then never again. You can fix this by storing the functions, without calling them:
commandslist = {"systemtime": systemtime,
"ping": ping,
"pwd": pwd,
"ifconfig": ifconfig,
"help": helpmenu,
"shop": shop}
I mention this because once you've made that fix, this is a lot easier to solve (and, it's far more correct).
First, I'd modify the line that cuts up the user input, since it's a little off as well for more complicated cases:
command, *options = userinput.split(" ")
Note the *
. This will collect every element after the first into options
. That means if the user enters somecommand arg1 arg2 arg3
, options
will hold (arg1, arg2, arg3)
.
After that runs, use command
to do a lookup to fetch the chosen function:
func = commandslist[command]
Then apply the options
arguments to the function:
func(*options)
*options
expands the sequence of options they gave into the argument list of the func
function.
Something like:
userinput = input(bash)
command, *options = userinput.split(" ")
func = commandlist[command]
print(func(*options))
Also, the whole
for i in commandslist:
if i == command:
part doesn't make sense if you think about it. You're checking for i
to be equal to command
. But if they're equal, why not just use command
directly like I'm showing? Yours will silently fail if they enter a bad command, when you likely want to actual show an error to them.
Also note, you'll want to do error handling, or do an if command in commandslist
check ahead of time. If the user enters a not existent key, or the wrong number of arguments, this will crash. You'll want to catch the KeyError
, and the TypeError
from the wrong number of arguments.
Upvotes: 2