Browse by Topic

# New in 13: Notebook Interfaces

Two years ago we released Version 12.0 of the Wolfram Language. Here are the updates in notebook interfaces since then, including the latest features in 13.0. The contents of this post are compiled from Stephen Wolfram’s Release Announcements for 12.1, 12.2, 12.3 and 13.0.

### The Desktop Interface to the Cloud (December 2020)

An important feature of Wolfram Notebooks is that they’re set up to operate both on the desktop and in the cloud. And even between versions of Wolfram Language there’s lots of continued enhancement in the way notebooks work in the cloud. But in Version 12.2 there’s been some particular streamlining of the interface for notebooks between desktop and cloud.

A particularly nice mechanism already available for a couple of years in any desktop notebook is the File > Publish to Cloud menu item, which allows you to take the notebook and immediately make it available as a published cloud notebook that can be accessed by anyone with a web browser. In Version 12.2 we’ve streamlined the process of notebook publishing.

When I’m giving a presentation I’ll usually be creating a desktop notebook as I go (or perhaps using one that already exists). And at the end of the presentation, it’s become my practice to publish it to the cloud, so anyone in the audience can interact with it. But how can I give everyone the URL for the notebook? In a virtual setting, you can just use chat. But in an actual physical presentation, that’s not an option. And in Version 12.2 we’ve provided a convenient alternative: the result of Publish to Cloud includes a QR code that people can capture with their phones, then immediately go to the URL and interact with the notebook on their phones.

There’s one other notable new item visible in the result of Publish to Cloud: “Direct JavaScript Embedding”. This is a link to the Wolfram Notebook Embedder which allows cloud notebooks to be directly embedded through JavaScript onto webpages.

It’s always easy to use an iframe to embed one webpage on another. But iframes have many limitations, such as requiring their sizes to be defined in advance. The Wolfram Notebook Embedder allows full-function fluid embedding of cloud notebooks—as well as scriptable control of the notebooks from other elements of a webpage. And since the Wolfram Notebook Embedder is set up to use the oEmbed embedding standard, it can immediately be used in basically all standard web content management systems.

We’ve talked about sending notebooks from the desktop to the cloud. But another thing that’s new in Version 12.2 is faster and easier browsing of your cloud file system from the desktop—as accessed from File > Open from Cloud and File > Save to Cloud.

### Yet More Notebookery (December 2020)

We invented notebooks—with all their basic features of hierarchical cells, etc.—back in 1987. But for a third of a century, we’ve been progressively polishing and streamlining how they work. And in Version 12.2 there are all sorts of useful and convenient new notebook features.

### Click to Copy

It’s a very simple feature, but it’s very useful. You see something in a notebook, and all you really want to be able to do with it is copy it (or perhaps copy something related to it). Well, then just use ClickToCopy:

 ✕ ClickToCopy[10!]

If you want to click-to-copy something unevaluated, use Defer:

 ✕ ClickToCopy[Plot[Sin[x], {x, 0, 10}], Defer[Plot[Sin[x], {x, 0, 10}]]]

++h has inserted a hyperlink in a Wolfram Notebook since 1996. But in Version 12.2 there are two important new things with hyperlinks. First, automatic hyperlinking that handles a wide range of different situations. And second, a modernized and streamlined mechanism for hyperlink creation and editing.

### Attached Cells

In Version 12.2 we’re exposing something that we’ve had internally for a while: the ability to attach a floating fully functional cell to any given cell (or box, or whole notebook). Accessing this feature needs symbolic notebook programming, but it lets you do very powerful things—particularly in introducing contextual and “just-in-time” interfaces. Here’s an example that puts a dynamic counter that counts in primes on the right-bottom part of the cell bracket:

 ✕ obj=AttachCell[EvaluationCell[],Panel[Dynamic[i]],{"CellBracket",Bottom},0,{Right,Bottom}]; Do[PrimeQ[i],{i,10^7}]; NotebookDelete[obj]

### Template Box Infrastructure

Sometimes it’s useful for what you see not to be what you have. For example, you might want to display something in a notebook as J0(x) but have it really be BesselJ[0, x]. For many years, we’ve had Interpretation as a way to set this up for specific expressions. But we’ve also had a more general mechanism—TemplateBox—that lets you take expressions, and separately specify how they should be displayed, and interpreted.

In Version 12.2 we’ve further generalized—and streamlined—TemplateBox, allowing it to incorporate arbitrary user interface elements, as well as allowing it to specify things like copy behavior. Our new TEX input mechanism, for example, is basically just an application of the new TemplateBox.

In this case, "TeXAssistantTemplate" refers to a piece of functionality defined in the notebook stylesheet—whose parameters are specified by the association given in the TemplateBox:

 ✕ RawBoxes[TemplateBox[<| "boxes" -> FormBox[FractionBox["1", "2"], TraditionalForm], "errors" -> {}, "input" -> "\\frac{1}{2}", "state" -> "Boxes"|>, "TeXAssistantTemplate"]]

### Form Notebooks (December 2020)

What’s the best way to collect structured material? If you just want to get a few items, an ordinary form created with FormFunction (and for example deployed in the cloud) can work well. But what if you’re trying to collect longer, richer material?

For example, let’s say you’re creating a quiz where you want students to enter a whole sequence of complex responses. Or let’s say you’re creating a template for people to fill in documentation for something. What you need in these cases is a new concept that we’re introducing in Version 12.2: form notebooks.

A form notebook is basically a notebook that is set up to be used as a complex “form”, where the inputs in the form can be all the kinds of things that you’re used to having in a notebook.

The basic workflow for form notebooks is the following. First you author a form notebook, defining the various “form elements” (or areas) that you want the user of the form notebook to fill in. As part of the authoring process, you define what you want to have happen to the material the user of the form notebook enters when they use the form notebook (e.g. put the material in a Wolfram Data Drop databin, send the material to a cloud API, send the material as a symbolic expression by email, etc.).

After you’ve authored the form notebook, you then generate an active version that can be sent to whoever will be using the form notebook. Once someone has filled in their material in their copy of the deployed form notebook, they press a button, typically “Submit”, and their material is then sent as a structured symbolic expression to whatever destination the author of the form notebook specified.

It’s perhaps worth mentioning how form notebooks relate to something that sounds similar: template notebooks. In a sense, a template notebook is doing the reverse of a form notebook. A form notebook is about having a user enter material that will then be processed. A template notebook, on the other hand, is about having the computer generate material which will then be used to populate a notebook whose structure is defined by the template notebook.

OK, so how do you get started with form notebooks? Just go to File > New > Programmatic Notebook > Form Notebook Authoring:

This is just a notebook, where you can enter whatever content you want—say an explanation of what you want people to do when they “fill out” the form notebook. But then there are special cells or sequences of cells in the form notebook that we call “form elements” and “editable notebook areas”. These are what the user of the form notebook “fills out” to enter their “responses”, and the material they provide is what gets sent when they press the “Submit” button (or whatever final action has been defined).

In the authoring notebook, the toolbar gives you a menu of possible form elements that you can insert:

Let’s pick Input Field as an example:

What does all this mean? Basically a form element is represented by a very flexible symbolic Wolfram Language expression, and this is giving you a way to specify the expression you want. You can give a label and a hint to put in the input field. But it’s with the Interpreter that you start to see the power of Wolfram Language. Because the Interpreter is what takes whatever the user of the form notebook enters in this input field, and interprets it as a computable object. The default is just to treat it as a string. But it could for example be a “Country” or a “MathExpression”. And with these choices, the material will automatically be interpreted as a country, math expression, etc., with the user typically being prompted if their input can’t be interpreted as specified.

There are lots of options about the details of how even an input field can work. Some of them are provided in the Add Action menu:

But so what actually “is” this form element? Press the CODE tab on the left to see:

What would a user of the form notebook see here? Press the PREVIEW tab to find out:

Beyond input fields, there are lots of other possible form elements. There are things like checkboxes, radio buttons and sliders. And in general it’s possible to use any of the rich symbolic user interface constructs that exist in the Wolfram Language.

Once you’ve finishing authoring, you press Generate to generate a form notebook that is ready to be provided to users to be filled in. The Settings define things like how the “submit” action should be specified, and what should be done when the form notebook is submitted:

So what is the “result” of a submitted form notebook? Basically it’s an association that says what was filled into each area of the form notebook. (The areas are identified by keys in the association that were specified when the areas were first defined in the authoring notebook.)

Let’s see how this works in a simple case. Here’s the authoring notebook for a form notebook:

Here’s the generated form notebook, ready to be filled in (assuming you have 12.2):

Here’s a sample of how the form notebook might be filled in:

And this is what “comes back” when Submit is pressed:

For testing, you can just have this association placed interactively in a notebook. But in practice it’s more common to send the association to a databin, store it in a cloud object, or generally put it in a more “centralized” location.

Notice that at the end of this example we have an editable notebook area—where you can enter free-form notebook content (with cells, headings, code, output, etc.) that will all be captured when the form notebook is submitted.

Form notebooks are very powerful idea, and you’ll see them used all over the place. As a first example, the various submission notebooks for the Wolfram Function Repository, Wolfram Demonstrations Project, etc. are becoming form notebooks. We’re also expecting a lot of use of form notebooks in educational settings. And as part of that, we’re building a system that leverages Wolfram Language for assessing responses in form notebooks (and elsewhere).

You can see the beginnings of this in Version 12.2 with the experimental function AssessmentFunction—which can be hooked into form notebooks somewhat like Interpreter. But even without the full capabilities planned for AssessmentFunction there’s still an incredible amount that can be done—in educational settings and otherwise—using form notebooks.

It’s worth understanding, by the way, that form notebooks are ultimately very simple to use in any particular case. Yes, they have a lot of depth that allows them to do a very wide range of things. And they’re basically only possible because of the whole symbolic structure of the Wolfram Language, and the fact that Wolfram Notebooks are ultimately represented as symbolic expressions. But when it comes to using them for a particular purpose they’re very streamlined and straightforward, and it’s completely realistic to create a useful form notebook in just a few minutes.

### Making Code Just a Bit More Beautiful (December 2020)

A core goal of the Wolfram Language is to define a coherent computational language that can readily be understood by both computers and humans. We (and I in particular!) put a lot of effort into the design of the language, and into things like picking the right names for functions. But in making the language as easy to read as possible, it’s also important to streamline its “non-verbal” or syntactic aspects. For function names, we’re basically leveraging people’s understanding of words in natural language. For syntactic structure, we want to leverage people’s “ambient understanding”, for example, from areas like math.

More than a decade ago we introduced as a way to specify Function functions, so instead of writing

 ✕ Function[x, x^2]

(or #2&) you could write:

 ✕ x |-> x^2

But to enter you had to type \[Function] or at least  fn , which tended to feel “a bit difficult”.

Well, in Version 12.2, we’re “mainstreaming” by making it possible to type just as |->

 ✕ x | - > x^2

You can also do things like

 ✕ {x, y} |-> x + y

as well as things like:

 ✕ SameTest -> ({x, y} |-> Mod[x - y, 2] == 0)

In Version 12.2, there’s also another new piece of “short syntax”: //=

Imagine you’ve got a result, say called res. Now you want to apply a function to res, and then “update res”. The new function ApplyTo (written //=) makes it easy to do that:

 ✕ res = 10
 ✕ res //= f
 ✕ res

We’re always on the lookout for repeated “lumps of computation” that we can “package” into functions with “easy-to-understand names”. And in Version 12.2 we have a couple of new such functions: FoldWhile and FoldWhileList. FoldList normally just takes a list and “folds” each successive element into the result it’s building up—until it gets to the end of the list:

 ✕ FoldList[f, {1, 2, 3, 4}]

But what if you want to “stop early”? FoldWhileList lets you do that. So here we’re successively dividing by 1, 2, 3, …, stopping when the result isn’t an integer anymore:

 ✕ FoldWhileList[Divide, 5!, Range[10], IntegerQ]

### Just Type TEX (December 2020)

The Wolfram Language is all about expressing yourself in precise computational language. But in notebooks you can also express yourself with ordinary text in natural language. But what if you want to display math in there as well? For 25 years we’ve had the infrastructure to do the math display—through our box language. But the only convenient way to enter the math is through Wolfram Language math constructs—that in some sense have to have computational meaning.

But what about “math” that’s “for human eyes only”? That has a certain visual layout that you want to specify, but that doesn’t necessarily have any particular underlying computational meaning that’s been defined? Well, for many decades there’s been a good way to specify such math, thanks to my friend Don Knuth: just use TEX. And in Version 12.2 we’re now supporting direct entry of TEX math into Wolfram Notebooks, both on the desktop and in the cloud. Underneath, the TEX is being turned into our box representation, so it structurally interoperates with everything else. But you can just enter it—and edit it—as TEX.

The interface is very much like the += interface for Wolfram|Alpha-style natural language input. But for TEX (in a nod to standard TEX delimiters), it’s +$. Type +$ and you get a TEX input box. When you’ve finished the TEX, just hit and it’ll be rendered:

Like with +=, if you click the rendered form, it’ll go back to text and you can edit again, just as TEX.

Entering TEX in text cells is the most common thing to want. But Version 12.2 also supports entering TEX in input cells:

What happens if you + evaluate? Your input will be treated as TraditionalForm, and at least an attempt will be made to interpret it. Though, of course, if you wrote “computationally meaningless math” that won’t work.

### It’s Going to Get Easier to Type Code in Notebooks (May 2021)

Ever since Version 3.0 (1996) -> has automatically turned into when you enter in code. And we’ve gradually added additional “input auto replacements”, the most recent being |-> turning into (\[Function]) in Version 12.2. In Version 12.3 we’re generalizing this whole mechanism (using the new AutoOperatorRenderings option), and we’re making <| ... |> automatically turn into <| ... |>, and [[  ... ]] turn into  ... .

So this means for example that instead of your code looking this

 ✕ Range[10][[ Nest[Flatten[RandomInteger[{1, 10}, {10, 2}][[#]]] &, 1, 5]]]

it’ll immediately turn into this more readable form right when you type it:

 ✕ Range[10][[ Nest[Flatten[RandomInteger[{1, 10}, {10, 2}][[#]]] &, 1, 5]]]

It might seem odd that it’s taken so many years to go from “automatic ” to “automatic 〚 〛”. But it’s a lot more subtle than you might think, and in fact it’s required a whole new as-you-type approach to code rendering. Back in Version 3.0, the idea was to replace -> with when you type it. So, for example, if you then backspace one character, you’ll delete the whole , rather than simply “removing the >” and reverting to -.

But if you’re dealing with [[ ... ]] you can’t just do this kind of “local replacement” without the potential for confusion with some ]] showing up as while others break apart into ]] as a result of routine editing.

In Version 12.3 what we’re doing is not to make replacements at all, but instead just to render specified sequences of characters (like ]]) in special ways. The result is that we can support very general “ligature-like” behavior, and that backspacing will always exactly reverse characters that were entered.

AutoOperatorRenderings will make code you type look nicer and be easier to read. But there’s a second, more significant change in the way you enter code that’s now available in Version 12.3. It’s still rather experimental, so it hasn’t been turned on by default, but you can explicitly turn it on if you want, just by evaluating

 ✕ CurrentValue[$FrontEnd, DelimiterAutoMatching] = True; or by checking the checkbox in the Interface tab of the Preferences: The basic idea—as the name DelimiterAutoMatching might suggest—is that when you type code, the delimiters you enter are automatically matched, as you type. So that means that if you type what you’ll actually see is: In other words, you’ll automatically get matched delimiters. (And by “delimiters”, we mean any of [ ... ], { ... }, ( ... ), " ... ", [[ ... ]], <| ... |> and (* ... *).) So what happens to your old typing habits? Well, you can still use them. Because you can enter ] to “type through” the closing ]. And that means you’re typing the exact same characters as before. But the important point is that you don’t need to. The ] is already there for you. Why is this important? Basically because it means you don’t have to think about matching your delimiters anymore. It’s done automatically for you. Ever since Version 3.0 (1996) we’ve had syntax coloring that indicates when delimiters haven't been closed—and to suggest that you should close them. But now the closing will just happen automatically. And in particular that means that expressions you’re typing will always “look complete”, and won’t have all kinds of structural changes happening as you enter each character. Needless to say, this is all a lot trickier than it might at first appear. Let’s say you’ve already entered a complicated expression, and now you add an opening delimiter inside it, or, worse, several opening delimiters. Where do the closing delimiters go? How much of the code that’s already there should they enclose? Sometimes it’s fairly obvious, but sometimes it’s not. You can always delete an inappropriately added closing delimiter, but we’re working hard to use the appropriate heuristics to either add the closing delimiter in the right place, or not add it at all. ### What's Wrong with That Code? Code Analysis & Assistance (May 2021) “Automate everything” is a big theme in what we’re trying to achieve with the Wolfram Language. So what about debugging? Is that something we can automate? We’ve been thinking about this for a long time, and in Version 12.3 we’ve introduced the first steps in our code analysis and assistance system. We’ve had things like syntax coloring and ^ for missing arguments for decades. And these are extremely useful. But what we want is something more global. Something not so much like spellchecking as like being able to say whether a piece of text means the right thing. One might think that there’s a kind of philosophical problem with this. In the Wolfram Language any piece of code—so long as it’s syntactically correct—is a symbolic expression which at some level means something. The question is whether that “something” is what you want. And the point is that by knowing the typical structure of “correct code” it’s often possible to make a very good guess. And that’s what our new code analysis system does. Say you have this simple piece of code:  ✕ If[x == y, f[e^2 + 4 e + 1], f[e^2 + 4 e + 1]] In Version 12.3 there’s a new context (“right-click”) menu item Analyze Cell. Here’s what it does: Code Analysis has noticed that the expressions on the two branches of the If are the same (as might have happened if you’d copied and pasted them, intending to change one, but forgetting). It’s not strictly “wrong” to have the branches the same, but it’s almost certainly not what you wanted, and if you had always wanted to give the same expression, then your code would be much less obscure if you just gave the expression. Here’s a marginally more complicated example:  ✕ Switch[x,1,a,2,b,True,c] Now we’ve clicked the description, and got a suggestion about how to fix things—which we can immediately implement just by clicking the suggestion. (The Code Analysis box effectively gives you a preview; click Apply Edits to actually change your original code.) Does Code Analysis catch real errors? Yes, and we’ve got evidence for that, because we’ve run it on our internal code, as well as on examples in our documentation. For example, in Version 12.2 the documentation for FitRegularization contained the example:  ✕ Length[basis = Flatten[ Table[Exp[-((t - \[Tau])/\[Sigma])^2] {1, Table[{Cos[\[Omega] t], Sin[\[Omega] t]}, {\[Omega], Drop[Subdivide[0., 150., n\[Omega]], 1]}]}, {\[Tau], Subdivide[0., 1., n\[Tau]]}]]] Run Code Analysis and you’ll see And, yes, that’s an error: there should be a comma in there. The Code Analysis in Version 12.3 is just a beginning. We’ll be adding many more cases and suggestions, derived both from symbolic analysis and machine learning. And the interface for the analysis will become more automatic—like spellchecking. But I think Code Analysis is going to be very important for both novice and experienced users of Wolfram Language, injecting automation into yet another domain. ### Type Fewer Brackets! (December 2021) When you first launch Version 13, and you type something like f[ you’ll see the following: What Version 13 is now doing is to automatically add matching brackets when it thinks it’s unambiguous to do so. The one thing to learn is that you can then “type through” the bracket; in other words if this case with the cursor right before the auto-added ] you explicitly type ] then no new ] will appear; the system will just “type through” the ]. There’s also the alternative of using ctrlspace to move to the right of the auto-added closing bracket. And, by the way, ctrlspace also “moves to the right” of the next closing bracket even when your cursor isn't immediately next to the bracket; it’ll do this even if the cursor is deep inside a nested structure. The automatching behavior (which you can turn off in the Preferences dialog if you really don’t like it) applies not only to [ ] but also to { }, ( ), [[ ]], <| |>, (* *) and (importantly) " ". And ctrlspace also works with all these kinds of delimiters. For serious user-experience aficionados there’s an additional point perhaps of interest. Typing ctrlspace can potentially move your cursor sufficiently far that your eye loses it. This kind of long-range cursor motion can also happen when you enter math and other 2D material that is being typeset in real time. And in the 1990s we invented a mechanism to avoid people “losing the cursor”. Internally we call it the “incredible shrinking blob”. It’s a big black blob that appears at the new position of the cursor, and shrinks down to the pure cursor in about 160 milliseconds. Think of this as a “vision hack”. Basically we’re plugging into the human pre-attentive vision system, that causes one to automatically shift one’s gaze to the “suddenly appearing object”, but without really noticing one’s done this. In Version 13 we’re now using this mechanism not just for real-time typesetting, but also for ctrlspace—adding the blob whenever the “jump distance” is above a certain threshold. You’ll probably not even notice that the blob is there (only a small fraction of people seem to “see” it). But if you catch it in time, here’s what you’ll see: ### Progress in Seeing the Progress of Computations... (December 2021) You’re running a long computation. What’s going on with it? We have a long-term initiative to provide interactive progress monitoring for as many functions that do long computations as possible. An example in Version 13.0 is that ParallelMap, ParallelTable, etc. automatically give you progress monitoring:  ✕ The display is temporary; it’s only there while the computation is running, and then it goes away. There are many other examples of this, and more to come. There’s progress monitoring in video, machine learning, knowledgebase access, import/export and various algorithmic functions:  ✕  ✕  ✕ Generally, progress monitoring is just a good thing; it helps you know what’s happening, and allows you to check if things have gone off track. But sometimes it might be confusing, especially if there’s some inner function that you didn’t even know was being called—and you suddenly see progress monitoring for it. For a long time we had thought that this issue would make widespread progress monitoring a bad idea. But the value of seeing what’s going on seems to almost always outweigh the potential confusion of seeing something happening “under the hood” that you didn’t know about. And it really helps that as soon as some operation is over, its progress monitors just disappear, so in your final notebook there’s no sign of them. By the way, each function with progress monitoring has a ProgressReporting option, which you can set to False. In addition, there is a global variable$ProgressReporting which specifies the default throughout the system.

It’s worth mentioning that there are different levels of “Are we there yet?” monitoring that can be given. Some functions go through a systematic sequence of steps, say processing each frame in a video. And in such cases it’s possible to show the “fraction complete” as a progress indicator bar. Sometimes it’s also possible to make at least some guess about the “fraction complete” (and therefore the expected completion time) by looking “statistically” at what’s happened in parts of the computation so far. And this is, for example, how ParallelMap etc. do their progress monitoring. Of course, in general it’s not possible to know how long an arbitrary computation will take; that’s the story of computational irreducibility and things like the undecidability of the halting problem for Turing machines. But with the assumption (that turns out to be pretty good most of the time) that there’s a fairly smooth distribution of running times for different subcomputations, it’s still possible to give reasonable estimates. (And, yes, the “visible sign” of potential undecidability is that a percentage complete might jump down as well as going up with time.)

### Wolfram|Alpha Notebooks (December 2021)

For many years we had Mathematica + Wolfram Language, and we had Wolfram|Alpha. Then in late 2019 we introduced Wolfram|Alpha Notebook Edition as a kind of blend between the two. And in fact in standard desktop and cloud deployments of Mathematica and Wolfram|Alpha there’s also now the concept of a Wolfram|Alpha-Mode Notebook, where the basic idea is that you can enter things in free-form natural language, but get the capabilities of Wolfram Language in representing and building up computations:

In Version 13.0 quite a lot has been added to Wolfram|Alpha-Mode Notebooks. First, there are palettes for directly entering 2D math notation:

There’s also now the capability to immediately generate rich dynamic content directly from free-form linguistic input:

In addition to “bespoke” interactive content, in Wolfram|Alpha-Mode Notebooks one can also immediately access interactive content from the 12,000+ Demonstrations in the Wolfram Demonstrations Project:

Wolfram|Alpha Notebook Edition is particularly strong for education. And in Version 13.0 we’re including a first collection of interactive quizzes, specifically about plots:

### Everything for Quizzes Right in the Language (December 2021)

Version 13.0 introduces the ability to create, deploy and grade quizzes directly in Wolfram Language, both on the desktop and in the cloud. Here’s an example of a deployed quiz:

It’s all based on the form notebook capabilities that we introduced in Version 12.2. But there’s one additional element: QuestionObject. A QuestionObject gives a symbolic representation of a question to ask, together with an AssessmentFunction to apply to the answer that’s provided, to assess, grade or otherwise process it.

In the simplest case, the “question to ask” is just a string. But it can be more sophisticated, and there’s a list of possibilities (that will steadily grow) that you can select in the authoring notebook:

(The construct QuestionInterface lets you control in detail how the “question prompt” is set up.)

Once you’ve created your quiz in the authoring notebook (and of course it doesn’t need to be just a “quiz” in the courseware sense), you need to deploy it. Settings allow you to set various options:

Then when you press Generate you immediately get a deployed version of your quiz that can, for example, be accessed directly on the web. You also get a results notebook, that shows you how to retrieve results from people doing the quiz.

So what actually happens when someone does the quiz? Whenever they press Submit their answer will be assessed and submitted to the destination you’ve specified—which can be a cloud object, a databin, etc. (You can also specify that you want local feedback given to the person who’s doing the quiz.)

So after several people have submitted answers, here’s what the results you get might look like:

 ✕

All in all, Version 13.0 now provides a streamlined workflow for creating both simple and complex quizzes. The quizzes can involve all sorts of different types of responses—notably including runnable Wolfram Language code. And the assessments can also be sophisticated—for example including code comparisons.

Just to give a sense of what’s possible, here’s a question that asks for a color to be selected, that will be compared with the correct answer to within some tolerance:

 ✕