Although this thread may be a little old, maybe someone who just recently is just starting out, and who tried to use the code from the lesson, and who found that it didn’t work (i.e., like me yesterday) might find this update helpful.
Here’s how I’ve reworked the Lambda code so as to actually perform the functionality as described in the Codecademy Build Your First Alexa Skill, “Add Persistence to Your Skill” course, the Session Attributes lesson, in the Create the Lambda Function exercise.
Having said all that, I could never have gotten to this point had it not been for the excellent work by maxibelino. Only by examining your code could I figure out what was wrong with the Codecademy code. Tip of the hat to you, my friend!
In this reworking, I have:
- taken AskQuestion out of the handlers section and made it a function call
- changed how AskQuestion is called now that it’s in a different scope
- added maxibelino’s excellent handling of the case of when we’re at the end of the deck,
- and also fixed some typos,
In all cases where I changed from Codecademy code, I’ve added // comments at the top of the block or at the end of the line.
One thing I haven’t done is to add maxibelino’s separate handling of languages (e.g., currentLanguages, see: then next lessons about persistance.). Well actually I did, but I backed it out to make this example look as much like the Codecademy code as possible in the hopes of helping someone else who is just starting.
Oh, and I never could get Alexa to understand my answer the the Python question about length being “len”. I guess it’s my accent or something.
'use strict';
var Alexa = require('alexa-sdk');
var flashcardsDictionary = [
{
question: 'how do you find the length of a string?',
rubyAnswer: 'length',
pythonAnswer: 'len', //TYPO: corrected capitalization, probably unimportant
javascriptAnswer: 'length'
},
{
question: 'how do you print to the console or terminal?',
rubyAnswer: 'puts',
pythonAnswer: 'print',
javascriptAnswer:'console.log'
},
{
question:'are boolean terms capitalized or not capitalized?',
rubyAnswer: 'not capitalized',
pythonAnswer: 'capitalized',
javascriptAnswer: 'not capitalized'
}];
var DECK_LENGTH = flashcardsDictionary.length;
var handlers = {
// Open Codecademy Flashcards
'LaunchRequest': function() {
this.attributes['language'] = '';
this.attributes['numberCorrect'] = 0;
this.attributes['currentFlashcardIndex'] = 0;
this.response
.speak('Welcome to Flashcards. In this session, do you want to test' + //CORRECTION: listen and speak reversed
' your knowledge in Ruby, Python, or Javascript?').listen(
'Which language would you like to practice?');
this.emit(':responseReady');
},
'SetMyLanguageIntent': function() {
this.attributes['language'] = this.event.request.intent.slots.languages.value;
var language = this.attributes['language'];
this.response
.speak('Okay, I will ask you some questions about ' +
language + '. Here is your first question. ' +
AskQuestion(this.attributes) ).listen(AskQuestion(this.attributes)); //CHANGED: definition of function call
this.emit(':responseReady');
},
// User gives an answer
'AnswerIntent': function() {
var userAnswer = this.event.request.intent.slots.answer.value;
var language = this.attributes['language'];
var languageAnswer = language + 'Answer';
var correctAnswer = flashcardsDictionary[this.attributes['currentFlashcardIndex']][languageAnswer];
this.attributes['currentFlashcardIndex']++; //MOVED: from after "if (userAnswer === correctAnswer)...else..." construct
if (userAnswer === correctAnswer) {
this.attributes['numberCorrect']++;
var numberCorrect = this.attributes['numberCorrect'];
// CHANGED: added test to give different response if we're at the end of the deck
// this.response
// .speak('Nice job! The correct answer is ' + correctAnswer + '. You ' +
// 'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
// language + ' questions correct.' + this.AskQuestion)
// .listen(this.AskQuestion);
if (this.attributes['currentFlashcardIndex'] < DECK_LENGTH) {
this.response
.speak('Nice job! The correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. ' + AskQuestion(this.attributes)) //CHANGED: definition of function call
.listen(AskQuestion(this.attributes)); //CHANGED: definition of function call
} else {
this.response
.speak('Nice job! The correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. That was the last question. Thank you and let\'s play again soon.' )
}
} else {
var numberCorrect = this.attributes['numberCorrect'];
// CHANGED: added test to give different response if we're at the end of the deck
// this.response
// .speak('Sorry, the correct answer is ' + correctAnswer + '. You ' +
// 'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
// language + ' questions correct. Here is your next question.' +
// this.AskQuestion).listen(this.AskQuestion);
if (this.attributes['currentFlashcardIndex'] < DECK_LENGTH) {
this.response
.speak('Sorry, the correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. ' + AskQuestion(this.attributes)) //CHANGED: definition of function call
.listen(AskQuestion(this.attributes)); //CHANGED: definition of function call
} else {
this.response
.speak('Sorry, the correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. That was the last question. Thank you and let\'s play again soon.' )
}
}
// this.attributes['currentFlashcardIndex']++; //MOVED: to before "if (userAnswer === correctAnswer)...else..." construct
this.emit(':responseReady');
},
// MOVED, CHANGED: this function was moved out of handlers and placed at bottom of index.js
// // Test my {language} knowledge
// 'AskQuestion': function() {
// var language = this.attributes['language'];
// var currentQuestion = flashcardsDictionary[this.attributes['currentFlashcardIndex']].question;
//
// return 'In ' + language +', ' + currentQuestion;
// },
// Stop
'AMAZON.StopIntent': function() {
this.response.speak('I heard the Stop Intent. Ok, let\'s play again soon.');
this.emit(':responseReady');
},
// Cancel
'AMAZON.CancelIntent': function() {
this.response.speak('I heard the Cancel intent. Ok, let\'s play again soon.');
this.emit(':responseReady');
}
};
exports.handler = function(event, context, callback){
var alexa = Alexa.handler(event, context);
alexa.registerHandlers(handlers);
alexa.execute();
};
// MOVED, CHANGED: this function was moved out of handlers and placed at bottom of index.js
function AskQuestion(attributes) {
var language = attributes['language'];
var currentQuestion = flashcardsDictionary[attributes['currentFlashcardIndex']].question;
return 'In ' + language +', ' + currentQuestion;
}
In case it should ever change, this is the code that I started from, copied from Exercise 8, Create the Lambda Function, accessed on 2 March 2018. This code was my starting point:
'use strict';
var Alexa = require('alexa-sdk');
var flashcardsDictionary = [
{
question: 'how do you find the length of a string?',
rubyAnswer: 'length',
pythonAnswer: 'Len',
javascriptAnswer: 'length'
},
{
question: 'how do you print to the console or terminal?',
rubyAnswer: 'puts',
pythonAnswer: 'print',
javascriptAnswer:'console.log'
},
{
question:'are boolean terms capitalized or not capitalized?',
rubyAnswer: 'not capitalized',
pythonAnswer: 'capitalized',
javascriptAnswer: 'not capitalized'
}];
var DECK_LENGTH = flashcardsDictionary.length;
var handlers = {
// Open Codecademy Flashcards
'LaunchRequest': function() {
this.attributes['language'] = '';
this.attributes['numberCorrect'] = 0;
this.attributes['currentFlashcardIndex'] = 0;
this.response
.listen('Welcome to Flashcards. In this session, do you want to test' +
' your knowledge in Ruby, Python, or Javascript?').speak(
'Which language would you like to practice?');
this.emit(':responseReady');
},
'SetMyLanguageIntent': function() {
this.attributes['language'] = this.event.request.intent.slots.languages.value;
var language = this.attributes['language'];
this.response
.speak('Okay, I will ask you some questions about ' +
language + '. Here is your first question.' +
this.AskQuestion).listen(this.AskQuestion);
this.emit(':responseReady');
},
// User gives an answer
'AnswerIntent': function() {
var userAnswer = this.event.request.intent.slots.answer.value;
var language = this.attributes['language'];
var languageAnswer = language + 'Answer';
var correctAnswer = flashcardsDictionary[this.attributes['currentFlashcardIndex']][languageAnswer];
if (userAnswer === correctAnswer) {
this.attributes['numberCorrect']++;
var numberCorrect = this.attributes['numberCorrect'];
this.response
.speak('Nice job! The correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct.' + this.AskQuestion)
.listen(this.AskQuestion);
} else {
var numberCorrect = this.attributes['numberCorrect'];
this.response
.speak('Sorry, the correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. Here is your next question.' +
this.AskQuestion).listen(this.AskQuestion);
}
this.attributes['currentFlashcardIndex']++;
this.emit(':responseReady');
},
// Test my {language} knowledge
'AskQuestion': function() {
var language = this.attributes['language'];
var currentQuestion = flashcardsDictionary[this.attributes['currentFlashcardIndex']].question;
return 'In ' + language +', ' + currentQuestion;
},
// Stop
'AMAZON.StopIntent': function() {
this.response.speak('Ok, let\'s play again soon.');
this.emit(':responseReady');
},
// Cancel
'AMAZON.CancelIntent': function() {
this.response.speak('Ok, let\'s play again soon.');
this.emit(':responseReady');
}
};
exports.handler = function(event, context, callback){
var alexa = Alexa.handler(event, context);
alexa.registerHandlers(handlers);
alexa.execute();
};