Wolfram Blog
Carlo Barbieri

New in the Wolfram Language: Ask

October 14, 2016 — Carlo Barbieri, Applied Research Group

Making web forms should be dead simple. That has been one of our goals at Wolfram Research since the release of the Wolfram Cloud. We’ve made smart input fields, powered by Wolfram|Alpha technology, that understand almost anything users type. We’ve designed FormFunction and APIFunction so that you can build forms and APIs with the same readable syntax. And now with the newest version of the Wolfram Language, you can build interactive web forms with dynamic branching and control flow using the Ask family of functions.

Would you like to learn how to build web forms with Ask?

What Ask Does

In a nutshell, AskFunction allows you to ask the user a series of questions—as in surveys, web orders, tax forms, quizzes, etc. To demonstrate, I have built a simple web form for my friends and family to RSVP to my upcoming party.

CloudDeploy[ AskFunction[ AskDisplay["RSVP for my party"]; Ask[{"name", "Enter name"} -> "String"]; Ask[{"attending", "Will you be attending?"} -> {"Yes" -> True, "No" -> False}]; Ask["name"] If[Ask["attending"], " is", " is not"] " attending." ] ]

RSVP for my party

Carlo

Will you be attending?

Carlo is attending

The first time I call Ask["name"], the web form prompts the user for input. When I call Ask["name"] the second time, the AskFunction remembers the user’s previous answer and uses that instead of asking again. See the example for yourself here.

This example isn’t really that different from what you can already do with FormFunction; Ask is not intended to replace FormFunction. Where Ask begins to really shine over its older brother is when you want to skip or tailor questions based on previous responses.

In the event a friend or family member says they are not attending my party, I would like to give them the opportunity to reconsider their tragic mistake. This is where AskConfirm comes in: AskConfirm asks users if they are OK with their answer; if they say no, AskConfirm effectively rewinds the computation and gives them a second chance to answer differently. And we can make it so only those who said they aren’t attending are prompted for confirmation. Try it out.

CloudDeploy[  AskFunction[   AskDisplay["RSVP for my party"];   Ask[{"name", "Enter name"} -> "String"];   If[    ! Ask[{"attending", "Will you be attending?"} -> {"Yes" -> True,         "No" -> False}],    AskConfirm["attending",      "You said you aren't attending. Would you like to change your \ answer?"]    ];   Ask["name"]  <> If[Ask["attending"], " is", " is not"]  <>     " attending."   ]  ]

You said you aren't attending. Would you like to change your answer?

And we can then ask more questions to those who are attending, such as whether they’ll be bringing a guest. There’s no need to ask those who aren’t attending if they are going to bring a guest—so we won’t! Try it out.

CloudDeploy[  AskFunction[   AskDisplay["RSVP for my party"];   AskAppend[{"name", "Enter name"} -> "String"];   If[    ! Ask[{"attending", "Will you be attending?"} -> {"Yes" -> True,         "No" -> False}],    AskConfirm["attending",      "You said you aren't attending. Would you like to change your \ answer?"];    Ask["name"][[1]] <> " is  not attending",    If[     Ask[{"plusone",         "Will you be bringing a plus one?"} -> {"Yes" -> True,         "No" -> False}],     AskAppend["name"]     ];    If[     Ask["plusone"],     StringJoin[      Riffle[Ask["name"], " and "] ,      " are attending"      ],     Ask["name"] <> " is attending"     ]    ]   ]  ]

Notice that when I ask for the user’s name and the name of the guest, I now use AskAppend instead of Ask. AskAppend["name"] does exactly what it sounds like it does—it appends the new answer for "name" to the previous answer. Unlike Ask, AskAppend can ask the same question multiple times and build up a list of each answer. So if I first answer AskAppend["name"] with “Carlo” and then later answer with “Ada,” when I call Ask["name"] again, the answer will be: {“Carlo”, “Ada”}.

I will also ask the user what sort of food they want—and once again, those who aren’t attending get to skip this question since it doesn’t apply. As an added bonus, I can utilize the built-in Wolfram Cloud storage and save the survey results to a Databin or CloudExpression. In less than ten minutes, I have built a functional web form with branching, using straightforward and declarative code. Here is the complete code, which you can try out in the cloud right now:

CreateCloudExpression[<|"attendance" -> {}, "foodCount" -> <||>|>,    "mysurveys/partyrsvp"]; CloudDeploy[  AskFunction[   AskDisplay["RSVP for my party"];   AskAppend[{"name", "Enter name"} -> "String"];   If[    ! Ask[{"attending", "Will you be attending?"} -> {"Yes" -> True,         "No" -> False}],    AskConfirm["attending",      "You said you aren't attending. Would you like to change your \ answer?"],    Ask[{"plusone",        "Will you be bringing a plus-one?"} -> {"Yes" -> True,        "No" -> False}];    If[     Ask["plusone"],     AskAppend["name"]];    Ask[{"food", "What food would you like?"} -> {"Pizza", "Sushi",        "Burgers", "Pasta"}]];   Module[{ce = CloudExpression["mysurveys/partyrsvp"]},    AppendTo[ce["attendance"], Ask["name"] -> Ask["attending"]];    AskTemplateDisplay[     If[       ! #attending,       "Sorry to hear you can't make it,  " <> #name,       ce["foodCount", #food]++;       Column[{         StringJoin[          "Thanks for responding! We look forward to seeing you, " ,           StringRiffle[#name, " and "] ,           "!"          ],         BarChart[          KeyValueMap[Labeled[#2, #1] &, ce["foodCount"]],           PlotLabel -> "Current Food Votes"          ]         }]       ] &     ]    ]   ],  Permissions -> "Public"  ]

Thanks for responding! We look forward to seeing you, Carlo and Ada!

A few other new functions I didn’t mention include AskedQ and AskedValue. AskedQ lets you check if a question has been asked already. AskedValue works like Ask, except it will not prompt the user if they have not been asked yet; the function will instead return Missing for unanswered questions.

What You Can Build with Ask

RSVP forms are far from the only thing you can build with Ask. We’ve been asked by many different users for this sort of control flow to be added to web forms. And we’re proud of how flexible this generic framework is. What I really love about the Wolfram Language is that behind a design that makes it simple to build 90% of applications, there is also deep customizability. With the basic tools of Ask, AskConfirm, AskAppend and AskDisplay, any problem with an “If this, do that” structure, or any flow chart, can be written as an AskFunction form. Here are just a few of the many applications you can now build.

Troubleshooting Guides

Have you ever needed to help friends or family members troubleshoot their computers? Build a troubleshooting guide web app and give your friends, family or clients an effective guide to fix their own problems.

Troubleshooting My Computer

Computer is really slow

Do you have an anti-virus program installed?

Tax/Legal Forms

A lot of factors go into finances—are you married, do you have children, how much do you make or spend? If you don’t have dependents, you should be able to skip over any question about dependents. Try out our example web form for computing your marginal tax rate.

Married filing jointly

What was your income in 2015?

Do you have any dependents?

You owe 16542.5 in taxes. Your marginal tax rate is 16.5%

Quizzes

FormFunction works fine for quizzes, but maybe you want to only display advanced questions once a student has demonstrated mastery of the beginner questions. Or use AskConfirm and AskAppend to loop on a particular question until the student has the correct answer.

What is 2+2?

What is x in 2x+1=3

What is sin(0)

You scored 33.33%. Would you like me to generate more practice problems?

What We’re Working on

Ask is still new, and the potential for what it can do is rapidly growing. Even now, we’re continuing to build on the Ask functionality and expand the functions in new directions. Coming down the pipeline are new projects that will bring the Ask syntax to different applications like chatbots and more. I’m genuinely proud of what we’ve accomplished so far and where we’re headed in the future. So if you’re interested in learning more about how to use these functions, please feel free to leave a comment!

Leave a Comment

5 Comments


Mark Ross

The code should be available as something other than an image. I cannot even use TextRecognize to get a good result from the poor quality image presented here.

Posted by Mark Ross    October 15, 2016 at 3:12 pm
Mark Ross

I should have said:
Thanks for the examples – this is an interesting capability to allow for various surveys and quizzes. Please publish the source code in a form other than an image so that we may use your example more readily.

Posted by Mark Ross    October 15, 2016 at 3:27 pm
John Erickson

Nice! I could have really used this a couple of weeks ago. Thanks for sharing.

Posted by John Erickson    October 17, 2016 at 10:39 am
    Carlo Barbieri

    Well, we’ve released it with 10.4 so you definitely could have :)

    Posted by Carlo Barbieri    October 27, 2016 at 9:24 am
Dan

I wish there were a better way to copy-paste the code — or a link to the corresponding notebook.

Posted by Dan    October 19, 2016 at 10:52 am


Leave a comment in reply to Mark Ross

Loading...

Or continue as a guest (your comment will be held for moderation):