# Python list “commander” (modify a list with user commands)

I made a program that can modify a list using commands that the user enters.

The commands that are supported are (used from actual program):

• /add [value1] [value2] [valueN]... - Add a value to the list
• /rvalue [value] - Removes a value from the list
• /rindex [index] - Removes the value at the specified index from the list
• /print - Prints the list
• /help - Lists every available command

Here is the code:

#Program to modify lists

value_list = []

def cmd_help():
print("/add [value1] [value2] [valueN]... - Add a value to the list")
print("/rvalue [value] - Removes a value from the list")
print("/rindex [index] - Removes the value at the specified index from the list")
print("/print - Prints the list")
print("/help - Lists every available command")

def get_command_params():
commands = {
"/add": lambda *value : value_list.extend(list(value)),
"/rvalue": lambda value : value_list.remove(value),
"/rindex": lambda value : value_list.pop(int(value)),
"/print": lambda : print(value_list),
"/help": cmd_help
}

while True:
input_cmd = input("Enter a command: ")

#Separate arguments
command = ""
current_args_index = -1
args = []
last_char = ""

for char in input_cmd:
#Update separator
if char == "/" or char == " ":
last_char = char

if last_char == "/":
command += char
elif last_char == "append":
args[current_args_index] += char
elif last_char == " ":
args.append("")
#To append individual characters to same index
last_char = "append"
++current_args_index

cmd = commands.get(command)
if cmd == None:
print("Invalid command!")
continue

return cmd, args

def main():
cmd_help()

#Wait for command
while True:
command, args = get_command_params()

#Execute command with arguments
try:
command(*args)

#Don't print success if command is print/help
if args != []:
print("Success!")
except IndexError:
print("Index out of range!")
except ValueError:
print("Element not found!")
except TypeError:
print("Invalid arguments! Type /help for help")

if __name__ == "__main__":
main()


## 1 Answer

value_list = []


Global variables are almost never necessary. If you are tempted to use a global, you have two choices:

1. Give the variable as an argument and reassign it to what the function returns (or just give it if the function mutates it).
2. Define a class and use instance attributes.

In this case, value_list is used by far too many things and with lambda functions and everything. Therefore, I would suggest that you define a Commands class.

"/add": lambda *value : value_list.extend(list(value))


You don't need to convert value to a list. That is just unnecessary processing time. A list can be extended by a list, a tuple, a string, a generator, ... whatever iterable you want.

"/rindex": lambda value : value_list.pop(int(value)),


I wouldn't convert it to an integer within a lambda function. I would create a whole function that uses a try block in case the user doesn't type a valid number. That is also helpful if the user does type a number, but types a number that is too big or too small.

elif last_char == "append"
...
last_char = "append"


Don't use magic numbers (or magic values). You should define a constant called APPEND that can really be assigned to any object except a single-character string.

++current_args_index


Python doesn't use ++. If x is 4, then +x is 4 and ++x is still 4. If x is -4, then +x is -4 and ++x is still -4. In other words, it does absolutely nothing. Python isn't like C where that increments current_args_index. If you want to increment it, do current_args_index += 1

cmd = ...
if cmd == None:
...


I have two problems. First, if you treat None as a special case, you can simply use a try block. Second, you should say is None, not == None because a class could define its __eq__ method to say that any instance is equal to None, but only None really is None.

Your main() function and how you use it looks terrific! You take care of each error separately, and you don't call main() unless your file is being run as a program. Keep it up!