144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
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() |