I'm trying to build a CLI that runs until the user decides to exit. The functionality of the CLI is to be able to explore a json-file by typing commands into the terminal while the program is running.
Right now commands are checked against if/else
statements, but I would like to add so that commands are checked in the manner of the argparse
module, but can't figure out how that is done while the program is running. Because I'm unable to figure that out, class methods are mapped to specific commands and executed when the command is specified without having to rely in if/else
logic.
The biggest issue is not single commands as -v
because they are easy to map to a function with dict. But commands that are -v LEAGUE
where LEAGUE
or -d LEAGUE SEASON TYPE
is much harder to map without creating big dictionaries since the arguments can be vary. Any suggestion how that can be improved is highly appreciated!
import os
import sys
class CLIStats:
def __init__(self):
"""Displays the welcome screen and loads the season-params.json
which contains the avalible leagues and their seasons that
can be downloaded. Pickled with pre-proccessed IDs is also loaded.
"""
self.header = self.header()
self.description = self.description()
self.commands = self.commands()
self.leagues = {'EN_PR': ['2019/2020', '2018/2019', '2017/2018', '2016/2017'],
'EU_CL': ['2019/2020', '2018/2019', '2017/2018', '2016/2017'],
'ES_PL': ['2019/2020', '2018/2019', '2017/2018', '2016/2017']}
@staticmethod
def header():
"""Display's welcome message"""
os.system('clear')
print('\t','*'*60)
print("\t\t*** Welcome - Football Stats generator ***")
print('\t','*'*60)
@staticmethod
def description():
"""Display's short description"""
print('Interface to download: \t playerstats \t fixturestats \t team standing \n')
print('Type "exit" to terminate shell')
@staticmethod
def commands():
"""Display's avalible commands and how to use them"""
commands = {'View Leagues': '-v',
'View League Seasons': '-v LEAGUE',
'Download stats': '-d LEAGUE SEASON TYPE',
'Help' : '-h',}
for key, value in commands.items():
print("{: <25} {}".format(key, value))
print('\n')
def view_leagues(self):
"""Prints out leagues in self.leagues"""
for league in self.leagues.keys():
print("{: <10}".format(league), end="")
print('\n')
def view_seasons(self, league):
"""Prints seasons for a league in self.leagues"""
if league in self.leagues:
seasons = self.leagues[league]
print(league,'seasons:')
for season in seasons:
print("{: <20}".format(season), end="")
print('\n')
else:
print(league, 'is not avalible')
print('\n')
def view_league_args(self):
"""Creates a list with set of args that can be passed
by user to execute view_league()"""
args = []
for league in self.leagues.keys():
args.append('-v' + ' ' + league)
return args
def main():
"""Runs the interface"""
interface = CLIStats()
cmd = {'-v': interface.view_leagues,
'exit': sys.exit,
'View Stats Type': '-s',
'-h' : 'interface.help', }
while True:
usr_command = input('CLIStats$ ')
if usr_command in cmd.keys():
cmd.get(usr_command)()
elif usr_command in interface.view_league_args():
league = usr_command.split(' ')[-1]
interface.view_seasons(league)
elif len(usr_command.split(' ')) == 4:
league = usr_command.split(' ')[1]
season = usr_command.split(' ')[2]
stat_type = usr_command.split(' ')[3]
interface.download_stats(league, season, stat_type)
else:
if usr_command.split(' ')[0] not in cmd.keys():
print('Command not valid')
else:
print('Could not find the specified params')
if __name__ == '__main__':
main()