Skip to content

Instantly share code, notes, and snippets.

@eloyz
Created December 5, 2016 16:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eloyz/f383f0cda280fb93b3b4913062733de5 to your computer and use it in GitHub Desktop.
Save eloyz/f383f0cda280fb93b3b4913062733de5 to your computer and use it in GitHub Desktop.
Alexa Skill: Math Drills
"""
This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit.
The Intent Schema, Custom Slots, and Sample Utterances for this skill, as well
as testing instructions are located at http://amzn.to/1LzFrj6
For additional samples, visit the Alexa Skills Kit Getting Started guide at
http://amzn.to/1LGWsLG
"""
from __future__ import print_function
from random import randint
class Question(object):
_questions = []
_index = 0
# Not really required, just keeping around for a little longer.
answer_to_int = {
"one": 1,
"two": 2,
"three": 3,
"four": 4,
"five": 5,
"six": 6,
"seven": 7,
"eight": 8,
"nine": 9,
"ten": 10,
"eleven": 11,
"twelve": 12,
"thirteen": 13,
"fourteen": 14,
"fifteen": 15,
"sixteen": 16,
"seventeen": 17,
"eighteen": 18}
def _generate(self, sort=None):
operand1 = randint(0, 9)
operand2 = randint(0, 9)
payload = {
'question': "{} plus {}?".format(operand1, operand2),
'answer': operand1 + operand2}
if sort is not None:
payload['sort'] = sort
return payload
def generate_questions(self, session):
"""Generate questions or retrieve from session."""
print('generate_questions session {}'.format(session))
if session.get('attributes', {}) and "questions" in session.get('attributes', {}):
self._questions = sorted(session['attributes']['questions'], key=lambda d: d['sort'])
else:
self._questions = [self._generate(i) for i in range(3)]
return self._questions
def get(self, key=None):
"""Return newest unanswered question."""
for index, question in enumerate(self._questions):
if not question.get('answered'):
self._index = index
if key:
return question[key]
return question
def mark_as_answered(self):
self._questions[self._index]['answered'] = True
def is_correct(self, answer):
_is_correct = self.get('answer') == int(answer)
if _is_correct:
self.mark_as_answered()
return _is_correct
def session_info(self):
return {'questions': self._questions}
_question = Question()
# --------------- Helpers that build all of the responses ----------------------
def build_output_speech(output, reprompt_text, should_end_session):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'reprompt': {
'outputSpeech': {
'type': 'PlainText',
'text': reprompt_text
}
},
'shouldEndSession': should_end_session
}
def build_response(session_attributes, speechlet_response):
return {
'version': '1.0',
'sessionAttributes': session_attributes,
'response': speechlet_response
}
# --------------- Functions that control the skill's behavior ------------------
def ask_question():
"""Ask math question."""
speech_output = _question.get('question')
reprompt_text = _question.get('question')
should_end_session = False
return build_response(_question.session_info(), build_output_speech(
speech_output, reprompt_text, should_end_session))
def validate_answer(intent):
"""Validate answer.
Ask next question or tell them their score.
"""
should_end_session = False
question = _question.get('question')
if 'Answer' in intent['slots'] and intent['slots']['Answer'].get('value'):
answer = intent['slots']['Answer']['value']
if _question.is_correct(answer):
question = _question.get('question')
if question is None:
speech_output = "Congratulations, you win! Show off."
reprompt_text = None
should_end_session = True
else:
speech_output = "Correct, what's {}?".format(question)
reprompt_text = question
else:
speech_output = "Your answer is {}. Please try again, what's {}?".format(answer, question)
reprompt_text = question
else:
speech_output = question
reprompt_text = question
return build_response(_question.session_info(), build_output_speech(
speech_output, reprompt_text, should_end_session))
def handle_session_end_request():
"""End session."""
speech_output = "Goodbye"
reprompt_text = None
should_end_session = True
return build_response({}, build_output_speech(
speech_output, reprompt_text, should_end_session))
# --------------- Events ------------------
def on_session_started(session_started_request, session):
""" Called when the session starts """
print("on_session_started requestId=" + session_started_request['requestId']
+ ", sessionId=" + session['sessionId'])
_question.generate_questions(session)
def on_launch(launch_request, session):
""" Called when the user launches the skill without specifying what they
want
"""
print("on_launch requestId=" + launch_request['requestId'] +
", sessionId=" + session['sessionId'])
return ask_question()
def on_intent(intent_request, session):
""" Called when the user specifies an intent for this skill """
print("on_intent requestId=" + intent_request['requestId'] +
", sessionId=" + session['sessionId'])
intent = intent_request['intent']
intent_name = intent_request['intent']['name']
# Dispatch to your skill's intent handlers
if intent_name == "MyAnswer":
return validate_answer(intent)
elif intent_name == "AMAZON.HelpIntent":
return ask_question()
elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
return handle_session_end_request()
else:
raise ValueError("Invalid intent")
def on_session_ended(session_ended_request, session):
""" Called when the user ends the session.
Is not called when the skill returns should_end_session=true
"""
print("on_session_ended requestId=" + session_ended_request['requestId'] +
", sessionId=" + session['sessionId'])
# add cleanup logic here
# --------------- Main handler ------------------
def lambda_handler(event, context):
""" Route the incoming request based on type (LaunchRequest, IntentRequest,
etc.) The JSON body of the request is provided in the event parameter.
"""
print("event.session.application.applicationId=" +
event['session']['application']['applicationId'])
"""
Uncomment this if statement and populate with your skill's application ID to
prevent someone else from configuring a skill that sends requests to this
function.
"""
# if (event['session']['application']['applicationId'] !=
# "amzn1.echo-sdk-ams.app.arn:aws:lambda:us-east-1:791663006172:function:myColorSkill"):
# raise ValueError("Invalid Application ID")
if event['session']['new']:
on_session_started({'requestId': event['request']['requestId']},
event['session'])
if event['request']['type'] == "LaunchRequest":
return on_launch(event['request'], event['session'])
elif event['request']['type'] == "IntentRequest":
return on_intent(event['request'], event['session'])
elif event['request']['type'] == "SessionEndedRequest":
return on_session_ended(event['request'], event['session'])
{
"intents": [
{
"intent": "MyAnswer",
"slots": [
{
"name": "Answer",
"type": "LIST_OF_ANSWERS"
}
]
},
{
"intent": "AMAZON.CancelIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"intent": "AMAZON.HelpIntent"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment