6. String Interpolation with Session Attributes - instruction error?


#1

In: 6. String Interpolation with Session Attributes the instructions say:

In the SetMyLanguageIntent speech output, replace the hard-coded instance of “Ruby” with the language session attribute, making sure to use interpolation where needed.

So I put

  .speak('Okay, I will ask you some questions about ' + this.attributes['language'] + 
               '. Here is your first question.' +

but it wasn’t accepted. I eventually gave up and it said the correct code was:

        .speak('Okay, I will ask you some questions about Ruby.' +
        language + '. Here is your first question.' +

But that neither replaces the word “Ruby”, nor does it use the session attribute.


#2

OK, so in question 7, it starts with:

In the SetMyLanguageIntent and AskQuestion function, create a variable called language and set it equal to the language session attribute. Replace the session attributes that are in the speech outputs with the variable language.

So they’ve mixed up 6 and 7


Alexa course, Skill from "Add Persistence to Your Skill"
#3

Now in question 7, it says:

In the SetMyLanguageIntent and AskQuestion function, create a variable called language and set it equal to the language session attribute. Replace the session attributes that are in the speech outputs with the variable language.

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

'AskQuestion': function() {
    this.attributes['language'] = this.event.request.intent.slots.languages.value;
    var language = this.attributes['language'];
    return 'In ' + language +', ' + currentQuestion;
  },

Apparently “correct” code according to “get answer”

'SetMyLanguageIntent': function() {
    this.attributes['language'] = this.event.request.intent.slots.languages.value;

    
    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');
  },

  'AskQuestion': function() {
    return 'In ' + language +', ' + currentQuestion;
  },

But that’s not what the question asked!


#4

OK, just found (and reported) my 7th issue with this new course, so I’m going to take a pause there - it’s just not ready yet.


#5

Hello,

Here is my updated and working Lambda function:

'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. ' + 
                askQuestion(this.attributes)).listen(askQuestion(this.attributes));
    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.toLowerCase() + 'Answer';
    var correctAnswer = flashcardsDictionary[this.attributes.currentFlashcardIndex][languageAnswer];
    var numberCorrect = 0;
    var message = '';

    this.attributes.currentFlashcardIndex++;
    
    if (userAnswer === correctAnswer) {
      this.attributes.numberCorrect++;
      numberCorrect = this.attributes.numberCorrect;
      
      message = 'Nice job! The correct answer is ' + correctAnswer + '. You ' +
            'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
            language + ' questions correct. ';

      if (this.attributes.currentFlashcardIndex < DECK_LENGTH) {
        message += 'Here is your next question. ' + askQuestion(this.attributes);
        this.response.speak(message).listen(askQuestion(this.attributes));
      } else {
        message += 'That was the last question. Thank you and let\'s play again soon.';
        this.response.speak(message);
      }
    } else {
      numberCorrect = this.attributes.numberCorrect;
      
      message = 'Sorry, the correct answer is ' + correctAnswer + '. You ' +
          'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
          language + ' questions correct. ';

      if (this.attributes.currentFlashcardIndex < DECK_LENGTH) {
        message += 'Here is your next question. ' + askQuestion(this.attributes);
        this.response.speak(message).listen(askQuestion(this.attributes));
      } else {
        message += 'That was the last question. Thank you and let\'s play again soon.';
        this.response.speak(message);
      }
    }

    this.emit(':responseReady');
  },

  // 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();
};

function askQuestion(attributes) {
    var language = attributes.language;
    var currentQuestion = flashcardsDictionary[attributes.currentFlashcardIndex].question;

    return 'In ' + language +', ' + currentQuestion;
}

#6

Aside

To make this code truly modern, we can take full advantage of string literals, or template strings that are so much more an elegant and readable form of interpolation.

    this.response.speak(`Ok, let's play again soon.`);

Right away we can see that escapement is no longer necessary. Anything that can be written in quotes can be written in backticks. The added plus is that variables and expressions can be embedded in the string.

    message = `Sorry, the correct answer is ${correctAnswer}. \
You have gotten ${numberCorrect} out of ${DECK_LENGTH} \
${language} questions correct. `;

Once you get into the habit of using backticks you will never go back to quotes. There are some situations that require standard quotes, but they are few.


#7

thanks a lot for fixing this issue. Do you have a solution for another code issue where scores/answers data is persisted to DynamoDB. even for that code we are getting error. appreciate your support. have a great weekend/week ahaed


#8

Yes, I do, I have just finished that part:

'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 the boolean terms true and false capitalized?',
       rubyAnswer: 'no',
       pythonAnswer: 'yes',
       javascriptAnswer: 'no'
     }];

var DECK_LENGTH = flashcardsDictionary.length;

var handlers = {

  // Open Codecademy Flashcards
  'LaunchRequest': function() {
    if(Object.keys(this.attributes).length === 0) {
        this.attributes.flashcards = {
          'currentLanguage': '',
          'languages': {
            'ruby': {
              'numberCorrect': 0,
              'currentFlashcardIndex': 0
            },
            'python': {
              'numberCorrect': 0,
              'currentFlashcardIndex': 0
            },
            'javascript': {
              'numberCorrect': 0,
              'currentFlashcardIndex': 0
            }
          }
        };

        this.response
            .listen('Welcome to Flashcards. Do you want to test your knowledge' +
            'in Ruby, Python, or Javascript?',
            'Which language would you like to practice?');

      } else {
        var currentLanguage = this.attributes.flashcards.currentLanguage.toLowerCase();
        var numberCorrect = this.attributes.flashcards.languages[currentLanguage].numberCorrect;
        var currentFlashcardIndex = this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex;

        this.response
            .listen('Welcome back to Flashcards. You are currently working on ' +
            currentLanguage + '. You\'re on question ' + currentFlashcardIndex +
            ' and have answered ' + numberCorrect + ' correctly.' +
            ' Do you want to test your knowledge in Ruby, Python, or Javascript?',
            'Which language would you like to practice?');

      }
    this.emit(':responseReady');
  },

  'SetMyLanguageIntent': function() {
    this.attributes.flashcards.currentLanguage = this.event.request.intent.slots.languages.value;
    var currentLanguage = this.attributes.flashcards.currentLanguage.toLowerCase();
    var currentFlashcardIndex = this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex;
    var message = '';
    
    if (currentFlashcardIndex < DECK_LENGTH) {
		message += 'Okay, I will ask you some questions about ' +
            currentLanguage + '. Here is your first question. ' + 
            askQuestion(this.attributes);
		this.response.speak(message).listen(askQuestion(this.attributes));
	} else {
		message += 'Sorry, there are no more questions for the ' + currentLanguage + ' language. Please, select another language.';
		this.response.speak(message).listen('Which language would you like to practice?');
	}

    this.emit(':responseReady');
  },

  // User gives an answer
  'AnswerIntent': function() {
    var currentLanguage = this.attributes.flashcards.currentLanguage.toLowerCase();
    var currentFlashcardIndex = this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex;
    var userAnswer = this.event.request.intent.slots.answer.value;
    var languageAnswer = currentLanguage.toLowerCase() + 'Answer';
    var correctAnswer = flashcardsDictionary[currentFlashcardIndex][languageAnswer];
	var numberCorrect = 0;
	var message = '';
	
	this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex++;

    if (userAnswer == correctAnswer){
        this.attributes.flashcards.languages[currentLanguage].numberCorrect++;
        numberCorrect = this.attributes.flashcards.languages[currentLanguage].numberCorrect;
		
		message = 'Nice job! The correct answer is ' + correctAnswer + '. You ' +
			'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
			currentLanguage + ' questions correct. ';
			
		if (this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex < DECK_LENGTH) {
			message += 'Here is your next question. ' + askQuestion(this.attributes);
			this.response.speak(message).listen(askQuestion(this.attributes));
		} else {
			message += 'That was the last question. Thank you and let\'s play again soon.';
			this.response.speak(message);
		}
    } else {
        numberCorrect = this.attributes.flashcards.languages[currentLanguage].numberCorrect;
      
		message = 'Sorry, the correct answer is ' + correctAnswer + '. You ' +
			'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
			currentLanguage + ' questions correct. ';

		if (this.attributes.flashcards.languages[currentLanguage].currentFlashcardIndex < DECK_LENGTH) {
			message += 'Here is your next question. ' + askQuestion(this.attributes);
			this.response.speak(message).listen(askQuestion(this.attributes));
		} else {
			message += 'That was the last question. Thank you and let\'s play again soon.';
			this.response.speak(message);
		}
    }

    this.emit(':responseReady');
  },

  // 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');
  },

  // Save state
  'SessionEndedRequest': function() {
    console.log('session ended!');
    this.emit(':saveState', true);
  }

};

exports.handler = function(event, context, callback){
    var alexa = Alexa.handler(event, context, callback);
    alexa.dynamoDBTableName = 'CodecademyFlashcards';
    alexa.registerHandlers(handlers);
    alexa.execute();
};

function askQuestion(attributes) {
    var currentLanguage = attributes.flashcards.currentLanguage.toLowerCase();
    var currentFlashcardIndex = attributes.flashcards.languages[currentLanguage].currentFlashcardIndex;
    var currentQuestion = flashcardsDictionary[currentFlashcardIndex].question;	
	
    return 'In ' + currentLanguage +', ' + currentQuestion;
}

#9

In the step 8/12 IAM Permissions, we need to also add a second permission, called “AWSLambdaBasicExecutionRole” - otherwise, we will not see any error logs in the CloudWatch.


#10

thanks a lot. I did the same soon after posting this question and it worked. I check in Dynamo DB as well for the record :slight_smile: thanks a lot for super fast response and support.


#11

scriptlover
I tried your response and i get “hmmm…maybe the skill codecademy can help, want to try it”
I am a beginner, but thought i was getting this. got a suggestion?