Wrote CLI based interface to test headless API
This commit is contained in:
		
							
								
								
									
										144
									
								
								server/CLIent.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								server/CLIent.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
import requests
 | 
			
		||||
from typing import Union
 | 
			
		||||
 | 
			
		||||
SERVER = 'http://127.0.0.1:5000/'
 | 
			
		||||
FETCH_PATH = 'api/fetch/'
 | 
			
		||||
 | 
			
		||||
INSTRUCTIONS = [
 | 
			
		||||
    '---- Instructions ----',
 | 
			
		||||
    'This quiz will present a series of multiple choice questions.',
 | 
			
		||||
    'You can select your response by entering the index number corresponding with your chosen option(s).',
 | 
			
		||||
    'For most questions, you may only select one option.',
 | 
			
		||||
    'Some questions allow multiple options to be selected, and will advice you accordingly.',
 | 
			
		||||
    'To select multiple options, enter their index number(s) separated by commas.'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
WELCOME = [
 | 
			
		||||
    '---- What *Wanderhome* Playbook Are You? ----',
 | 
			
		||||
    '',
 | 
			
		||||
    '*Wanderhome* is about going on a journey, and reflecting on how the journey changes us.',
 | 
			
		||||
    'The road is full of myriad travellers, each with their rich lives and stories.',
 | 
			
		||||
    'This quiz will help you figure out what kinds of stories you will bring to the table.',
 | 
			
		||||
    'Will you join me?',
 | 
			
		||||
    ''
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
GOODBYE = [
 | 
			
		||||
    '---- Thank you for taking the What Wanderhome Playbook Are You? Quiz ----',
 | 
			
		||||
    'Programmed and Written by Vivek Santayana',
 | 
			
		||||
    'Based on the table-top role-playing game *Wanderhome* by Jay Dragon, published by Possum Creek Games.',
 | 
			
		||||
    'Check out Wanderhome at https://possumcreekgames.com/en-gb/pages/wanderhome',
 | 
			
		||||
    'I strongly recommend this game: it is amazing!',
 | 
			
		||||
    '',
 | 
			
		||||
    'Good bye, and may your journeys surprise you!',
 | 
			
		||||
    ''
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
def sanitise_text(raw_text:str) -> str:
 | 
			
		||||
    format_replacements = {
 | 
			
		||||
        '<p>': '',
 | 
			
		||||
        '</p>': '\n',
 | 
			
		||||
        '<em>': '*',
 | 
			
		||||
        '</em>': '*',
 | 
			
		||||
        '<strong>': '**',
 | 
			
		||||
        '</strong>': '**',
 | 
			
		||||
        'æ': 'æ',
 | 
			
		||||
        '‘': '‘',
 | 
			
		||||
        '’': '’',
 | 
			
		||||
        'ï': 'ï'
 | 
			
		||||
    }
 | 
			
		||||
    for key, value in format_replacements.items():
 | 
			
		||||
        raw_text = raw_text.replace(key, value)
 | 
			
		||||
    
 | 
			
		||||
    return raw_text
 | 
			
		||||
 | 
			
		||||
def render(output:list):
 | 
			
		||||
    print('\n'.join(['', *output, '']))
 | 
			
		||||
    x = input('Press Enter to proceed.')
 | 
			
		||||
 | 
			
		||||
def render_question(question) -> str:
 | 
			
		||||
    print(sanitise_text(raw_text=question['question']))
 | 
			
		||||
    print('-- Options --')
 | 
			
		||||
    for index, answer in enumerate(question['answers']):
 | 
			
		||||
        print(index, sanitise_text(raw_text=answer))
 | 
			
		||||
    print('')
 | 
			
		||||
    prompt = f'Please select up to {question["select"]} options, separated by commas: ' if question['select'] > 1 else 'Please select an answer: '
 | 
			
		||||
    return input(prompt)
 | 
			
		||||
 | 
			
		||||
def parse_input(raw_answer) -> list:
 | 
			
		||||
    try: return list(set(int(answer) for answer in raw_answer.split(',')))
 | 
			
		||||
    except: return [ ]
 | 
			
		||||
 | 
			
		||||
def process_input(answer_input:list, question:dict) -> Union[list, int]: return answer_input[0] if question['select'] == 1 else answer_input
 | 
			
		||||
 | 
			
		||||
def show_input_error(): input('\n *** Your response was invalid. Please try again *** \n\nPress enter to retry.')
 | 
			
		||||
 | 
			
		||||
def validate_answer(answers:list, question:dict) -> bool:
 | 
			
		||||
    def check_range(answer:int) -> bool: return answer >= 0 and answer < len(question['answers'])
 | 
			
		||||
    def check_input_number(answers:list) -> bool: return len(answers) > 0 and len(answers) <= question['select']
 | 
			
		||||
    if not check_input_number(answers=answers): return False
 | 
			
		||||
    try: return all([check_range(answer=int(answer)) for answer in answers])
 | 
			
		||||
    except ValueError: return False
 | 
			
		||||
 | 
			
		||||
def render_questions() -> list:
 | 
			
		||||
    answers = []
 | 
			
		||||
    try:
 | 
			
		||||
        questions = requests.get(url=f'{SERVER}{FETCH_PATH}questions/').json()
 | 
			
		||||
    except Exception as exception:
 | 
			
		||||
        print(exception)
 | 
			
		||||
        quit()
 | 
			
		||||
    for index, question in enumerate(questions):
 | 
			
		||||
        answer_valid = False
 | 
			
		||||
        while not answer_valid:
 | 
			
		||||
            print('')
 | 
			
		||||
            print(f'---- Question {index + 1} ----')
 | 
			
		||||
            answer = render_question(question)
 | 
			
		||||
            answer = parse_input(answer)
 | 
			
		||||
            answer_valid = validate_answer(answer, question)
 | 
			
		||||
            if not answer_valid: show_input_error()
 | 
			
		||||
        answers.append(process_input(answer, question))
 | 
			
		||||
    try: return requests.post(url=f'{SERVER}api/submit/',json=answers).json()
 | 
			
		||||
    except Exception as exception:
 | 
			
		||||
        print(exception)
 | 
			
		||||
        quit()
 | 
			
		||||
 | 
			
		||||
def render_results(results:list):
 | 
			
		||||
    print('\n---- Results ----\n')
 | 
			
		||||
    plural = len(results['playbooks']) > 1
 | 
			
		||||
    print(f'Your { "results are" if plural else "result is"}:')
 | 
			
		||||
    for playbook in results['playbooks']:
 | 
			
		||||
        name = list(playbook.keys())[0]
 | 
			
		||||
        data = list(playbook.values())[0]
 | 
			
		||||
        animals = ''
 | 
			
		||||
        for index, animal in enumerate(data['animals']):
 | 
			
		||||
            article = 'an' if animal[0] in ['a','e','i', 'o', 'u'] else 'a'
 | 
			
		||||
            conjunction = ', or ' if index == len(data['animals']) - 2 else '.' if index == len(data["animals"]) - 1 else ', '
 | 
			
		||||
            animals += f'{article} {animal}{conjunction}'
 | 
			
		||||
        print(f'\n**The {name[0].upper()}{name[1:]}**\n(pp.{data["pages"]})\n')
 | 
			
		||||
        print(sanitise_text(data['flavour']),'\n')
 | 
			
		||||
        print(sanitise_text(data['blurb']),'\n')
 | 
			
		||||
        print('You are alive.\nYour care is ',sanitise_text(data['care']),'.\n')
 | 
			
		||||
        print('Your animal form is ', animals, '\n')
 | 
			
		||||
        print('You can always:')
 | 
			
		||||
        for action in data['actions']:
 | 
			
		||||
            print('-- ', sanitise_text(action))
 | 
			
		||||
        input('\nPress enter to continue.')
 | 
			
		||||
    print('\ny-- Your score for each playbook: --')
 | 
			
		||||
    for playbook, score in results['all_playbooks'].items(): print(f'The {playbook[0].upper()}{playbook[1:]}: {score*"x"} ({round(100*score/results["max_score"])}%)')
 | 
			
		||||
 | 
			
		||||
def run_quiz():
 | 
			
		||||
    render(output=WELCOME)
 | 
			
		||||
    render(output=INSTRUCTIONS)
 | 
			
		||||
    run = True
 | 
			
		||||
    while run:
 | 
			
		||||
        render_results(render_questions())
 | 
			
		||||
        repeat_prompt_valid = False
 | 
			
		||||
        while not repeat_prompt_valid:
 | 
			
		||||
            repeat_prompt = input('\nDo you want to do the quiz again? (y) Yes / (n) No: ')
 | 
			
		||||
            if repeat_prompt.lower() in ['y', 'n', 'yes', 'no']: repeat_prompt_valid = True
 | 
			
		||||
            if not repeat_prompt_valid: show_input_error()
 | 
			
		||||
        run = True if repeat_prompt.lower() in ['y', 'yes'] else False
 | 
			
		||||
    render(GOODBYE)
 | 
			
		||||
 | 
			
		||||
"""Running the Quiz"""
 | 
			
		||||
if __name__ == '__main__': run_quiz()
 | 
			
		||||
		Reference in New Issue
	
	Block a user