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()
|