# How We Navigated a Hybrid Remote Learning Environment Using Wolfram Technology

The past year of learning ushered in a variety of new experiences for instructors and students alike, and the United States Military Academy at West Point was no exception. In addition to masks in the classroom, reduced class sizes to allow for social distancing, rigorous testing and tracing efforts, and precautionary remote video classes, we have also needed to adjust aspects of our teaching styles. While such adjustments were voluntary, to enhance the discussion I chose to teach several lessons outside under large white tents and even in stadium bleachers to safely enable larger conversations with my cadets. Sometimes this meant carrying a large whiteboard with a tripod out to the stadium. At other times it meant putting quiz-style questions on a website so that students could submit answers via forms that were easier to grade while allowing everyone to work at a safe distance on individual devices.

Despite the obstacles, every opportunity to develop leaders is still a privilege, and part of my journey toward self-improvement as well. I am fortunate enough to have a classroom full of motivated individuals who volunteered for the challenges of a West Point education and show up daily ready to perform. Several of my experiences (including building PDF slides of plots and other forms not mentioned here) are captured in the talk I gave during the Wolfram Technology Conference this past October. In this blog post, I share some of the whys and hows of our use of various tools in the Wolfram Language and Mathematica to achieve our goals.

## Problem-Solving Process Overview

At West Point, we are optimized for leaders of character who solve problems (find out more at the school’s website). It is in that light that every cadet receives an interdisciplinary education of which mathematics is but one important part. As part of the required math curriculum, over the past several years I have taught a combination of courses focused on mathematical modeling, calculus and differential equations to solve problems. We teach a problem-solving process that focuses on three steps. First, we transform a real-world situation into a mathematical model. Then, we use various traditional formulas along with modern technologies to solve that mathematical model. Finally, we must interpret that mathematical solution in a way that enables our leaders to make effective decisions. (In fact, this process is very similar to other problem-solving processes, including Wolfram’s computational thinking approach.)

When we utilize technologies like the Wolfram Language as tools to solve problems more efficiently, we free up additional time to focus on transforming the problem and interpreting the possible solutions available to decision makers.

Many students face significant challenges in visualizing a new concept being described, particularly in a remote learning environment. All West Point cadets are required to take a course that uses math models to apply problem-solving skills to real-world situations. With effective instructor design, Wolfram forms enable students to focus on the math concept by limiting the code required to examine similar problems.

My own use of the Wolfram Language through Mathematica has traditionally been limited to building and plotting functions in order to better visualize both problems and their solutions. However, the COVID-19 environment shifted post–spring break classes entirely online, and I suddenly found myself seeking to enhance the visual tools I use to explain math concepts. After a deliberate and rigorous planning process, we were fortunate to be able to hold mostly in-person classes this fall. My efforts to expand my skills to include the Wolfram Cloud started with a desire to improve some plots by using more of the plotting options. As I began exploring more of the robust built-in documentation that Wolfram provides (for example: to get examples and ideas about the options for the function `Plot`, open a notebook cell and run `?Plot`), I became more aware of the vast variety of functions available to Wolfram users.

## Comparing Function Behavior

I had previously used the `Manipulate` command to show differences between how different functions behave. You can quickly select a different function from the drop-down menu and see how the plot changes as the value of the input variable changes.

✕
Manipulate[ Plot[f[x], {x, -5, 5}, PlotLabels -> ToString[f[x]]], {f, {Sin, Cos, Sqrt, Power, Exp, Function[x, x^3 + 12]}}] |

You can also use `Manipulate` to demonstrate a concept, like the average rate of change between two points by drawing the secant line:

✕
ratechangeplot = Framed[Manipulate[ Plot[{x^2, m x + b /. Solve[{xs^2 == m xs + b, xf^2 == m xf + b}, {m, b}, Reals]}, {x, -7, 7}, PlotLegends -> {"Function", "Rate Change Line"}, Axes -> True, GridLines -> {{xs, xf}, {xs^2, xf^2}}, ImageSize -> 240, PlotLabel -> "Rates of Change"], {{xs, 2, "start point x"}, -4, 6, 1, Appearance -> "Labeled"}, {{xf, 6, "second point x"}, -4, 6, 1, Appearance -> "Labeled"}], FrameMargins -> 20, Background -> Lighter[Yellow, 0.8]] |

If you want to stick to static plots, you can use `TabView` to combine multiple plots that you desire students to compare:

✕
Framed[Labeled[ TabView[{"Linear" -> Plot[2 x + 4, {x, -2 Pi, 2 Pi}, PlotRange -> Automatic], "Power" -> Plot[Power[x, 2] + 7, {x, -2 Pi, 2 Pi}], "RootPower" -> Plot[Sqrt[x - 4] + 7, {x, -2 Pi, 20}], "Exponential" -> Plot[Exp[x - 3] + 7, {x, -2 Pi, 30}], "Trig Sine" -> Plot[Sin[x + 5] + 7, {x, -2 Pi, 2 Pi}], "Trig Cosine" -> Plot[Cos[x] - 5, {x, -2 Pi, 2 Pi}] }], Style["Overview of Different Types of Functions Shifted", 14, Red], Top], Background -> LightBlue, FrameMargins -> 20] |

## FormPage and FormFunction Examples Deployed to the Wolfram Cloud

I believe the `CloudDeploy` function is a powerful tool for enhancing learning in a remote and hybrid learning environment. Next, I’ll offer a few examples of how I have employed them to enhance my class for parts of the past two semesters. `Manipulate`, along with the `FormFunction` and `FormPage` functions, offered additional approaches to allow students to discover certain math relationships for themselves. Further browsing led me to chapter 36 of Stephen Wolfram’s *An Elementary Introduction to the Wolfram Language* and to both free and paid interactive courses available via instructors at Wolfram U.

Visualizations created with `Manipulate`, `FormFunction` and `FormPage` can be shared and displayed with the ease of a web browser simply by using `CloudDeploy` (for objects) and `CloudPublish` (for whole notebooks) coupled with a freely available Wolfram Cloud account. The cell output is a URL that you can then share with anyone with a web browser. If you desire, you can even build some of these objects on your next trip to the park via a tablet or smartphone with the Wolfram Cloud app. `CloudDeploy` requires you to set the `Permissions` option appropriately in order to share with each other.

If you assign a manipulate or any other object a name (e.g. `ratechangeplot`), then it can be quickly deployed to be accessible in any web browser by calling `CloudDeploy`:

✕
CloudDeploy[ratechangeplot, \ "https://www.wolframcloud.com/obj/1ad8a238-fc25-4352-a149-\ 424577029cde", Permissions -> "Public"] |

`FormPage` offers the flexibility to see the output of the form and then readjust the inputs on the same webpage. Keeping the entire problem on the same viewing screen enables students to more directly associate the relationship between changing the value of an input and seeing the corresponding effect on the output. With multiple adjustments and repetitions visualizing similar problems, hopefully students are able to discover relationships that may have been more difficult to understand using static figures alone. (Be aware that depending on what you are trying to achieve, some deployments using `FormFunction` and `FormPage` stored in the cloud can cost Wolfram Cloud Credits. If that doesn’t align with your desires, you may consider just sharing entire notebooks or having students download and run the forms locally on their machines.)

Over the semester, I built the following form examples to explain concepts of a discrete dynamical system involving recursion equations, flow state diagrams, transformation matrices and scatter plots.

### Linear Discrete Dynamical System (Based on Difference Equations)

You can create your single linear discrete dynamical system (DDS) consisting of a recursion equation *p*(*n*) and the initial condition *p*(0) to model growth, decay, oscillation or equilibrium:

✕
lineardds = FormPage[{{"a", "Enter number a parameter for linear term with multiplication \ change to recursion equation:"} -> "Number", {"d", "Enter number d parameter for fixed amount arithmetic change to \ recursion equation:"} -> "Number", {"p0", "Enter number p0 for initial condition of sequence:"} -> "Number", {"n", "Enter number n for length of sequence:"} -> "Number", {"value", "Enter output value of the sequence to determine how many \ iterations n are required to reach it:"} -> "Number", {"color", "Select plot color:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black}}, Column[{p[n_] := #a*p[n - 1] + #d, Framed[Labeled[#value, "Desired Output", Top]], Framed[Labeled[ N[Solve[#d/(1 - #a) + #a^n*(#p0 - (#d/(1 - #a))) == #value, n, Reals]], "Iterations to Achieve Desired Output", Top]], Framed[Labeled[p[0] = #p0, "Initial Condition", Top]], Framed[Labeled[#d/(1 - #a), "Equilibrium Value", Top]], TableForm[Table[{n, p[n]}, {n, 0, #n}], TableHeadings -> {None, {"n Iteration", "p[n] Sequence Output"}}], Show[ListPlot[Table[{n, p[n]}, {n, 0, #n}], PlotStyle -> #color, PlotLabel -> "Linear Discrete Dynamical System", LabelStyle -> Directive[Black, Bold]], ImageSize -> Large]}] &, AppearanceRules -> <| "Title" -> "Enter A Linear Discrete Dynamical System of the form: " \ CloudGet["https://wolfr.am/Su7md6Ca"], "Description" -> "This form takes the parameters for your recursion equation and \ your initial condition and returns a table of the output of your \ Discrete Dynamical System as well as a plot of the behavior of the \ system p_n out to the nth iteration of the sequence. The form uses \ the analytic form of the solution to determine the number of \ iterations required to reach a certain result."|>, PageTheme -> "Red"]; |

You can then send the result to a webpage, again using `CloudDeploy`:

✕
CloudDeploy[lineardds, \ "https://www.wolframcloud.com/obj/4a55b0f7-028d-48cc-b07e-\ 4be5d1dd3030", Permissions -> "Public"] |

### Visualizing Network Flow with a Graph Edge List

In another example, you can create a graph in which you can change the edge list and weights or select colors and shapes.

✕
graphplot = FormPage[{{"graphtitle", "Enter the Title of the Graph:"} -> "String", {"edges", "Enter edges inside {} separated by a comma with -> for directed \ and <-> for undirected edges (e.g. \ {v1\[Rule]v2,v2\[Rule]v3,v3\[Rule]v1}):"} -> "String", {"weights", "Enter corresponding edge weights inside {} separated by a \ comma, (e.g. {w1,w2,w3}):"} -> "String", {"vertcolor", "Select vertex/node color:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black, Gray}, {"vertshape", "Select vertex/node shape:"} -> {"Triangle", "Square", "Rectangle", "Pentagon", "Hexagon", "Octagon", "Circle"}, {"edgecolor", "Select edge/arc color:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black, Gray}, {"weightcolor", "Select weight label color:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black, Gray}}, Show[Graph[ToExpression[#edges], EdgeWeight -> ToExpression[#weights], EdgeLabels -> "EdgeWeight", VertexLabels -> "Name", VertexLabelStyle -> 20, VertexStyle -> #vertcolor, EdgeStyle -> {Thick, #edgecolor}, EdgeLabelStyle -> Directive[#weightcolor, 20], VertexShapeFunction -> #vertshape, VertexSize -> Small, PlotLabel -> #graphtitle, LabelStyle -> Directive[Bold, Black, 24]], ImageSize -> Large] &, PageTheme -> "Red"] |

Here’s this example deployed to a webpage:

### Visualizing Matrix Vector Transformations

A third example involves visualizing the transformation of a two-dimensional vector. Input into the form your 2×2 matrix and 2×1 vector and see how the matrix transforms the vector to a new location.

✕
tranmatplot = FormPage[{{"a", "Enter a 2x2 matrix as a list {} with each row as a sublist {} \ separated by a comma , (e.g. {{1,2},{2,1}}) :"} -> "String", {"x", "Enter a 2x1 vector x as a list {x,y} separated by a comma , \ (e.g. {1,2}) :"} -> "String", {"color2", "Select Original vector x plot color:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black}, {"color", "Select transformed vector b color after being Multiplied by \ Matrix A:"} -> {Red, Green, Blue, Purple, Pink, Orange, Black}}, Show[Rasterize[ Row[{Framed[ Labeled[MatrixForm[a = Function[t, ToExpression[#a]][t]], " Matrix A ", Top]], Framed[Labeled[ MatrixForm[x = Function[t, ToExpression[#x]][t]], " Vector x ", Top]], Framed[Labeled[Det[a], "Determinant of A", Top]], Framed[Labeled[MatrixForm[b = a . x], " Vector b ", Top]], Show[ Graphics[{{#color2, Thick, Arrow[{{0, 0}, x}]}, {#color, Thickness[Medium], Arrow[{{0, 0}, b}]}}, Axes -> True, GridLines -> Automatic, PlotLabel -> "Vector x becomes b after Transformation by Matrix A"], ImageSize -> Large]}], ImageResolution -> 450], ImageSize -> Large] &, PageTheme -> "Red"] |

Here’s the webpage:

### Visualizing a Scatter Plot Using FormFunction

Looking at examples from the documentation, it becomes clear the function `FormFunction` is very similar to `FormPage`, with the function arguments first taking the desired user-provided inputs followed by a comma, then explaining what computation must be performed on those inputs. The formatting of the output is followed by an `&` symbol. In the computation part of the form command, the inputs get a `#` symbol in front of the name provided for that input.

An example more appropriate for `FormFunction` was when I wanted to allow students to upload a CSV file with two columns corresponding to inputs and outputs of a dataset:

I also arranged for the Wolfram Cloud to provide a visual scatter plot of the data points using a `FormFunction` that included the `ListPlot` and `Table` commands in the output:

To achieve this, we created a form that takes a CSV file of two columns of data where it interprets the first column as input and the second as output. The display outputs a table of values and a scatter plot.

✕
plotCSVdata = FormFunction[{"data" -> "CSV"}, Row[{ListPlot[#data, ImageSize -> Large], TableForm[#data, TableHeadings -> {None, {"input", "output"}}]}] &, "PNG"] |

As with other expressions, you can assign any cloud object a local name during deployment:

✕
obj = CloudDeploy[plotCSVdata] |

You can always adjust the `Permissions` option to be `"Public"` or `"Private"` later by using the `SetOptions` function on the previously deployed cloud object.

✕
SetOptions[obj, Permissions -> "Public"] |

While cadets at West Point receive a site license as part of the institutional purchase of Mathematica (you can check with Wolfram Customer Service to see if your university already has a license you can use), the open availability of a free Wolfram Cloud account to anyone with an email address makes it possible for students everywhere to see what you created if you set the permissions to `"Public"`. They can also download your code within the Wolfram Cloud webpage and then make adjustments to fit their own needs.

## Scanning QR Codes, Embedding in Another Site and Publishing Your Notebook as a Website

You can also copy and paste the generated website address as a link on any learning management system (LMS). If you use the Publish to Cloud option under the File menu, you don’t even have to type the `CloudDeploy` command. The popup window also provides an equivalent QR code that any user can point a smartphone camera at and receive a notification redirecting them to your Wolfram Cloud page. With minimal HTML or CSS skills, you can also display your notebook or object as an interactive frame inside another webpage by using the `EmbedCode` command:

✕
EmbedCode[ CloudObject[ "https://www.wolframcloud.com/obj/timothy.newlin/Published/\ Hyperlinks_MA103InstructorExample.nb"]] |

I usually just share the website address for a notebook of what I did in class, but I had one student who for whatever reason was slow to visit any of the notebook sites I was sharing. So when he asked me for assistance with something related to a concept I had shared via posting the Wolfram Cloud website link in our LMS with the QR code the previous day, I first asked him to point his camera at the QR code. He was surprised to discover how easy it was to see an example of everything I had done the class before. Here is an example of creating a QR code for the earlier linear discrete dynamical system:

✕
BarcodeImage[ ToString["https://www.wolframcloud.com/obj/4a55b0f7-028d-48cc-b07e-\ 4be5d1dd3030"], "QR", 250] |

Maybe you have students who ask if they can take a picture of the boards in your classroom during class. An alternative for any notebook code is just to publish it to the cloud. You may also desire to build and share a central repository of all the notebooks and objects that you share with students. A simple approach could be to build a blank notebook with all the pictures and hyperlinks to all the addresses for the cloud objects you want to share. Then run `CloudPublish` at the very end of the page and provide your students with that single link. You can then add and remove other objects from the page by republishing an updated notebook to that web address throughout the course. An example website of other items I worked on this semester is posted here.

Another way to get there is by pointing the camera on your device at the following QR code:

✕
BarcodeImage[ ToString["https://www.wolframcloud.com/obj/timothy.newlin/Published/\ Hyperlinks_MA103InstructorExample.nb"], "QR", 250] |

## Final Thoughts

I hope you have found these many suggestions and the associated examples helpful. As students continue to learn in environments that may be remote, in person or something in between based on changing conditions, we continue to navigate the challenges of inspiring and enabling them to solve difficult problems. Regardless of the learning environment, as teachers, mentors or coaches, you have all experienced the spark of joy that occurs when you see a student realize a concept or relationship that was previously unknown to them. Whether you choose to simply publish an entire Wolfram Notebook to the cloud to share with your class or you decide to dig into the options of the `FormFunction` and `FormPage` functions to create some new tools that enhance your class, I wish you luck and offer my support. Thanks for journeying along with me. Stay safe, and happy lessons ahead!

## Acknowledgment and Disclaimer

I’d like to thank Mads Bahrami for his help, and also the Wolfram Blog team for their invitation. I’d also like to thank my fellow faculty members for teaching support throughout the semester. The views expressed are my own and do not necessarily represent the views of West Point, the United States Army or any agency of the United States government.

*Guest author Timothy Newlin is an assistant professor in the Department of Mathematical Sciences at the United States Military Academy in West Point, New York.*

Get full access to the latest Wolfram Language functionality with a Mathematica 12.2 or Wolfram|One trial. |

## Comments