如何使用 python 在 alexa 中验证插槽数据是数字

How to validate slot data is numeric in alexa with python

所以我的 Alexa 技能要求发票金额。

用户应该说 "My invoice is for one hundred dollars."

我的示例话语是 "my invoice is for {invoiceAmount} dollars" 其中 {invoiceAmount} 是一个 Amazon.NUMBER 插槽

如果用户说一个数字,一切正常。但是,如果他们不这样做,那么代码就会崩溃,Alexa 就会退出我的技能。例如,如果用户说 "My invoice is for baseball dollars."

这是我处理此意图的代码:

def set_amount_in_session(intent, session):
    card_title = "Set Invoice Amount"
    should_end_session = False

    if 'invoiceAmount' in intent['slots']:
        if intent['slots']['invoiceAmount']['value'] is not None:
            invoice_amount = intent['slots']['invoiceAmount']['value']
            try:
                val = int(invoice_amount)
            except ValueError:
                val = 0
            if val != 0:
                session['attributes']['invoiceAmount'] = int(invoice_amount)
                speech_output = "The invoice amount is " + str(invoice_amount) + " dollars. "
                card_output =   "Invoice Amount $" + str(invoice_amount)
                reprompt_text = "Please tell me the terms of the invoice."
            else:
                speech_output = "I'm not sure what the invoice amount is. " \
                                "Please try again."
                card_output =   "I'm not sure what the invoice amount is. " \
                                "Please try again."
                reprompt_text = "I'm not sure what the invoice amount is. " \
                                "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                                "my invoice is for one hundred and fifty dollars."
        else:
            speech_output = "I'm not sure what the invoice amount is. " \
                            "Please try again."
            card_output =   "I'm not sure what the invoice amount is. " \
                            "Please try again."
            reprompt_text = "I'm not sure what the invoice amount is. " \
                            "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                            "my invoice is for one hundred and fifty dollars."
    else:
        speech_output = "I'm not sure what the invoice amount is. " \
                        "Please try again."
        card_output =   "I'm not sure what the invoice amount is. " \
                        "Please try again."
        reprompt_text = "I'm not sure what the invoice amount is. " \
                        "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                        "my invoice is for one hundred and fifty dollars."
    return build_response(session['attributes'], build_speechlet_response(
        card_title, speech_output, card_output, reprompt_text, should_end_session))

当我在 Amazon Developer Console 中测试这段代码时,它运行良好,但在我的 Echo Dot 上却失败了。

如果我说 "My invoice is for one hundred baseball dollars" 它能够处理响应并说它不确定发票金额是多少。

如果我说 "My invoice is for baseball one hundred dollars" 它实际上会忽略 "baseball" 并将发票金额设置为 100 美元,我可以接受。

但是,如果我说 "My invoice is for baseball dollars" 它会失败并说 "There was a problem with the requested skills response" 并且它会关闭技能。

所以我想通了。

当我说 "my invoice is for one hundred dollars" 我得到:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.386d4fe9-dc04-4376-8e30-dec3205484fe",
  "locale": "en-US",
  "timestamp": "2017-08-08T14:59:43Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount",
        "value": "100"
      }
    }
  }
}

这当然是有效值,所以它被正确处理了。

当我说 "my invoice is for one hundred baseball dollars" 我得到:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.c1b4a1d0-4949-4247-b326-a582ce4826b4",
  "locale": "en-US",
  "timestamp": "2017-08-08T15:01:09Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount",
        "value": "?"
      }
    }
  }
}

我不确定这个值是空值还是不是整数,但由于我检查了这两种情况,所以这不是问题

问题是当我说 "my invoice is for baseball dollars" 时,invoiceAmoutn 槽没有值:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.a046d29b-581c-484a-8879-abe979ec6286",
  "locale": "en-US",
  "timestamp": "2017-08-08T14:51:36Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount"
      }
    }
  }
}

显然,没有 "value" 与 "value" 为空不同。所以我不得不在我的代码中再添加一次检查,以首先查看是否有值。所以这是我的新代码,现在还检查是否有值:

if 'invoiceAmount' in intent['slots']:
    if 'value' in intent['slots']['invoiceAmount']:
        if intent['slots']['invoiceAmount']['value'] is not None:
            invoice_amount = intent['slots']['invoiceAmount']['value']
            try:
                val = int(invoice_amount)
            except ValueError:
                val = 0
            if val != 0:
                NOW I HAVE A VALID VALUE AND CAN EXECUTE MY CODE

有了这个改变,我似乎已经解决了我的问题。