CSC 15 Lab : Alexa Skills and State Machines ############################## Part I. ############################## In part I of this assignment, you are to modify the "student info" program I've demonstrated, and for which you can find the code for on the homepage. In particular, the following refinements should be made: 1. The ID numbers should be read out digit by digit. 2. The names should be matched regardless of lower or upper case. Some of the names were not recognized properly for this reason. Given a string s, s.lower() returns (non-destructively) a version of s with all characters in lower case. 2b. Two names may refer to the same person if one is a prefix of the other. For example, "John" and "Johnathan", "Edward" and "Ed" are probably the same person. But it's not a certainty: "Matthew" and "Matt" may actually refer to different people. You still want to prefer exact matches. If all you can find is an inexact match, you need to have Alexa confirm that this is in fact the person you're referring to. The state machine has to be modified to add in this feature. You want to have a session like the following: Alexa: Which student would you like information for? User: Johnathan Alexa: Do you mean John? User: Yes or No Alexa: either read out info or ask for another student name. Remember that given string s, s[0:n] is the substring from s[0] to s[n-1]. 3. When a student's name has been correctly recognized and Alexa has read the basic info for the student, she should then give the user the option of also reading out the student's transcript in the manner demonstrated in class. Add this feature too. ***First, sketch the new statemachine carefully BEFORE coding anything. The state machine design is a required part of the assignment. You may not start coding before the prof approves of your state machine. 4. Build your alexa skill following my demonstration and the online tutorial. In your AWS account, select the "Lambda" service and create a new function. Follow the demonstration in class (choose defaults and the lambda_execution model). Select Python 3.6 (consistent with the .zip folder) and stufacts.handler as the handler (must match the name of your file and the name 'handler' as defined towards the end of your program). You need to place your program and all dependent programs (stu.py) into the lambda_shell.zip folder: zip lambda_shell.zip filename will either add or replace filename in the zip folder. If you don't have zip as a command line tool in windows (should have on mac/linux) you can do pacman -S zip in the msys window to install it. Unload the .zip to AWS lambda. Now on the client side, sign into an Amazon developer account and navigate to creating an Alexa skill. For simplicity, you can just select the Edit JSON tab an paste in the following, before modifying it for your needs (change the invocationName): { "interactionModel": { "languageModel": { "invocationName": "student info", "intents": [ { "name": "AMAZON.FallbackIntent", "samples": [] }, { "name": "AMAZON.CancelIntent", "samples": [] }, { "name": "AMAZON.HelpIntent", "samples": [] }, { "name": "AMAZON.StopIntent", "samples": [] }, { "name": "AMAZON.NavigateHomeIntent", "samples": [] }, { "name": "AMAZON.YesIntent", "samples": [ "yes" ] }, { "name": "AMAZON.NoIntent", "samples": [ "no" ] }, { "name": "NameIntent", "slots": [ { "name": "student_name", "type": "AMAZON.FirstName" } ], "samples": [ "{student_name}", "student {student_name}", "I'd like information for {student_name}" ] } ], "types": [] } } } Now to connect the client side with the server side, you need to select "Endpoint". Select AWS Lambda ARN, then goto the AWS console and copy the arn at the top, which should be something like arn:aws:lambda:us-east-1:129636253206:function:studentinfo paste this in the "Default region" slot back at the developer console. Then copy the "Skill ID" from the client side and, on the AWS server side, in the "Add triggers" window select 'Alexa Skills Kit', and paste in the Skill ID into the entry at the bottom. Save. Back on the client side, save the endpoint, go back to the Edit Json tab, click save model, then build. Then, after build is successful, you can then test the program. ## In case of an error, copy the JSON Input from the test window, and goto the AWS side. Select configure test, and create a new test by replacing the default json with the json that produced the error, and click on test. You can examine the details and logs. If you still can't find the error, insert log points into your code like this: logger.info("inside Yes hander, program state is "+str(Myprogam.state)") When constructing large strings, remember that numerical values must be converted into strings. The online Alexa Python SDK also have instructions that explain all this, but your best bet is to ask the professor or TA for help if you're having problems. 5. (optional). You may modify the program to be about something other than students, but the basic structure of the program (the state machine) should stay intact. ############################### Part II ############################### Your goal for part II is to write a memory teaser game similar to the one demonstrated in class. Your program needs to have at least the same features as my program. For the first part of the assignment, you need to write a program that's independent of any user interface. In my program, there is an array of colors: Colors = ["blue","red","green","yellow","purple","brown","orange","pink","white","gray"] You can replace colors with something else, like domesticated animals. The idea is that the player/user is first shown (read) these colors, "color number 0 is blue, color number 1 is red, etc.", then asked a series of questions: "what is color number 2?", etc. Each time an answer is entered, a response (correct/incorrect) is given and a score is tabulated. The player is given a final score at the end along with an appropriate message such as "congratulations, you have perfect memory." 1. Write a function (can be independent of any class) def genpermutation(n): that returns an array of n numbers and which contains each of 0...n-1 exactly once. For example, genpermutation(5) may return [3,4,2,0,1], that is, an array of length 5 containing each of the numbers 0-4. You function needs to be "truly random" and efficient. Now write a funtion def applyperm(P,A): that destructively applies permutation P to A. Now calling applyperm(genpermutation(len(Colors)),Colors) # will scramble your colors. You want to permute the colors at the beginning so that the game is different each time. Alternatively, you can make the game even harder my using a permutation to read out the numbers and colors at the beginning. 2. Design a state machine for your game. Be as careful as possible. Each state should return some string for alexa to speak. But transitions between states are either handled by the states themselfs, or be triggered by an alexa "intent". If a state transition does not depend on a voice Intent, then it should be made by one function calling another in your program. 3. Write a class for your game. Although it's for an Alexa program, the class should be independent of the Alex interface. As further hint, in my class I have the following instance variables and their initial values: self.state = 0 self.index = 0 # can also use self.state-2 to index Colors self.QuestionOrder = genpermutation(len(Colors)) # order of numbers to ask Although your class should be interface independent, you should write it so that it can be used in both a synchronous or asynchronous (event-driven) environment. In your program, to get the user response to a question such as "what is color number 3?", you need to do the following in your "handle" method: def handle(self, handler_input): slots = handler_input.request_envelope.request.intent.slots human_res = slots["answer_value"].value # ... human_res will be a string representing user response (which should be a color) { "interactionModel": { "languageModel": { "invocationName": "memory teaser", "intents": [ { "name": "AMAZON.FallbackIntent", "samples": [] }, { "name": "AMAZON.CancelIntent", "samples": [] }, { "name": "AMAZON.HelpIntent", "samples": [] }, { "name": "AMAZON.StopIntent", "samples": [] }, { "name": "AMAZON.NavigateHomeIntent", "samples": [] }, { "name": "AMAZON.YesIntent", "samples": [] }, { "name": "AMAZON.NoIntent", "samples": [] }, { "name": "ColorIntent", "slots": [ { "name": "answer_value", "type": "AMAZON.Color" } ], "samples": [ "it is {answer_value}", "is it {answer_value}", "{answer_value}" ] }, { "name": "AMAZON.RepeatIntent", "samples": [ "repeat", "say again", "again" ] } ], "types": [] } } }