[WSG26] Daily Study Group: Creative Computation

A Wolfram U Daily Study Group on Creative Computation begins on May 18th 2026.

Join me, Eryn Gillam, and a group of fellow learners to learn how to use Wolfram Language in creative ways. Our topics for the study group include creating computational art, computational poetry, audio visualization, and building two types of video games. Along the way, we’ll learn how to code effectively in Wolfram Language.

No prior Wolfram Language experience is required.

Please feel free to use this thread to collaborate and share ideas, materials, and links to other resources with fellow learners.

Dates

May 18th-22nd

11am-12:30pm CT (4-5:30pm GMT)

Register Here

6 Likes

I’ve been doing Rope Flow for about 10 years. It’s a means of moving laterally with a jump rope without jumping over the rope. Here is a sample of the Rope Flow “Dragon Roll” from an instruction video on YouTube.
I’m marking the middle and endpoints of my rope with distinct bright colors and will make a short slow-motion video of the “Dragon Roll” this weekend. I’ll use the Wolfram Language’s simple motion-tracking capability and try to plot the rope’s motion in 3D. Next, I’ll see if the WL can identify the 3D curve of the “Dragon Roll”. Based on the figure-eight (i.e., lemniscate) shadow of the path, I’ve got a pretty good guess what the path might be. That Mathworld entry even mentions my guess. We shall see. :slight_smile:

This is a marvelous STEM application. Students learn about sine waves in geometry and more advanced HS math classes. The “Dragon Roll” allows them to stand under and make sinusoidal waves – front-back, left-right, and up-down – all at the same time.

You can see the component sine waves by orienting this Wolfram 3D graphic to various sides. The monolith is in the center to represent how the rope criss-crosses over the flow-roper. Note: you can only change the 3D orientation if the animation is not playing. I apologize for the janky animation of the red ball. I need to figure out how to make it smoother when running off of a cloud computer. You can download the Notebook or just copy the expression into your local version of Mathematica.

We learn Rope Flow moves by imitating someone else. That starts with awkward movements, but our CNS rapidly smoothes and polishes the movement. You don’t have to know diddly about math to do Rope Flow, but it adds a delightful dimension to the game. If my creative computation works, it can be a great launching point for other computational explorations of ropes and sine waves I think that captures the spirit of what Rory and Eryn teach with this course.

If this works, I may reach out to a couple of the Rope Flow schools to show them the idea. I’m looking forward to [reviewing] Rory’s Creative Computation class next week.

1 Like

I’ve been wondering if it’s possible to draw with differential equations or vector fields. In particular, can I learn to teach others how to draw with differential equations? It’s mainly a math-art problem, I suppose, which problem I have yet to figure out. Anyway, Phil inspired me to share.

I can teach people to draw with algebraic equations. Mostly, it’s showing them how to figure it out for themselves. Desmos used to have spectacular competitions. Here’s a 3d graphic one of my students produced with Mathematica:

Another student created a very nice-looking wristwatch. He did it in a modular way, so I could work with him to make it Dynamic[] so that it always tells the right time.

But creating images with differential equations seems hit and miss, and mostly miss. Here are a couple of examples I created. I have a version of the second one in which Dynamic[] animates the snowflakes along the phase curves outside the tree. In each graphic, there is just one vector field, and the stream lines are created by a single StreamPlot[]. The star in the first one consists of phase curves, inspired by an allium schubertii I grew in my garden and use for the star on my Christmas tree. The star in the second is just a polygon, because I could do no better.

They’re my babies, so of course I like them. They make it feel possible to design a vector field whose flow reflects a given shape, or at least some shapes.

2 Likes

Inspired by class today…

A couple of things:

  • The image data has three numbers in a list {r, g, b} that represent a color.
    RGBColor @@ {r, g, b} yields the color RGBColor[r, g, b].
  • It turns out that the position of a color datum in the data is flipped from the usual graphics coordinates: Horizontal and vertical positions are switched, and the vertical position increase from top to bottom instead of from the bottom up. That’s the reason for the odd matrix multiplication ({{0, 1},{-1, 0}}).position.

The code layers dots on top of each other, decreasing in radius from maxRadius pixels down to 1 pixel. The color for each dot corresponds to the color of the pixel in the image at the center of the dot. Layering the smaller dots on top allows the resolution to improve. Lots of things to play with: how the radii change, how large the disks, how many disks — all affect the texture, identifiability. You can play with the color space to get a reddish tiger by replacing Extract[data, position]] with Clip[RotationMatrix[-Pi/3, {1,1,1}].Extract[data, position]].

1 Like

I stupidly exited today’s study group before the feedback form showed up. Can I somehow send feedback anyway?

I extended the project a bit and replaced everything. Well, except “the” since the entity type “Determiner” had a random (grammatical) number, and I could not determine the number in WL; and “to”, which is an infinitive marker, not a preposition. Another problem is than RandomWord[type] sometimes comes up with words that cannot be of the type, except in the sense that in English most words can be used metaphorically as most parts of speech. And sometimes in the cloud, the random word generation is too slow for the time limits in the cloud. Of course, random words generate nonsense, but sometimes it’s fun.

◔
1 Like

I did the Computational Poetry project (yesterday) a bit differently - I jumped into assuming you’d want to generate a lot of haikus from that template - 100s or 1000s. I dunno, maybe your actual goal is writing a program to evaluate an haiku to see if it makes sense, give it a score for symbolism. Whatever. Anyway, I compute all possible replacements first and then use those to generate haiku rapidly.

Notebook is here on Wolfram Cloud - download it and evaluate it locally.

Computing (and caching) the set of all valid replacements, in the first cell, takes ~2m elapsed time on my laptop. Then use 2nd cell’s Manipulate to generate as many random haiku as you like. (Evaluate locally because it seemed to take forever in the cloud, before I killed it.)


(BTW, is it just me or are the “free response” quiz items useless and frustrating for others too? You can never answer them correctly. They’re frustrating because you then go into the next quiz, knowing how useless they are, and answer it anyway, hoping for the best. But no, still impossible to get the correct answer. Even when copying the answer from the Wolfram documentation! I hit this on each and every webinar, and now of course this study group. Geez, Wolfram, just give up on them already.)

Sound/Audio project is here on Wolfram Cloud - an ~80MB download if you want to try it (because it has embedded audio and an embedded result VU meter).

Nothing special on the visualization, the only reasons I wanted to upload it were:

  • I really liked the AudioIntervals[] function, especially with the "VoiceInactivity" criteria - that’s useful!
    • In this particular case I used it to eliminate VU meter fluctuations due to the background “hiss” of the recording
  • Everyone should listen to King George VI’s 1939 “war speech” at least once (the movie version condensed it slightly, though didn’t remove any really important part, IMO).

Post on “The King’s Speech” was mine - for some reason the forum didn’t attribute it to me.

1 Like

Quiz 5 Problem 1 seems incorrect - my guess is the 4th choice (“D”) is backwards from what was intended. No?

I don’t think the staff want to talk about particular quiz answers. For what it’s worth, I also tend to think there’s something wonky about that question. OTOH, there is value in deeply understanding the difference between == and ===; that’s the real point of the question.

You reminded me of one nice feature of the Wolfram Documentation. You can enter any function shortcut into the search panel at the top of the documentation (e.g., ===, @@@, @, etc.) and the documentation will give you the Full Form of that function shortcut and go to the appropriate documentation page.

If you have Wolfram Language installed in your local machine, it’s incredibly useful to have the documentation also installed. Each page in the documentation is a full live Wolfram Language Notebook, and you’re more than welcome to start actively evaluating expressions in the middle of any documentation page. There’s something deeply Stephen Wolfram about that; I could imagine him doing that when he’s typing in Notebooks for hours every day. It almost feels like cheating.

The “updating name” bug is a long-standing one in the Wolfram Community software. It’s some sort of race condition in the code. It’s been around for many years; you’ll find numerous entries with that handle in discussions that have lots of postings (like the WSG discussions). It should be fixable, but the bug appears to be tolerated. There was a discussion about bugs and desired features in the community.wolfram.com software in another discussion here Thanks to Wolfram U student @Tingting Zhao for that discussion.

A legitimate question is why Wolfram Research doesn’t just transition over to licensing and using Discourse. I don’t know the answer to that; I’ve never seen any staff address the question. I tried to ask in a couple of live Q&A sessions, but my questions were ignored. This discussion software does have some magic so that embedded Notebooks are available as Wolfram Cloud objects, but (AFAIK) that should be eminently doable as a Discourse plugin. My main guess: it simply isn’t a priority. Long-standing users here learn to cope with the community.wolfram.com limitations. IMHO, the main casualty is newbies in Wolfram U courses, who have to learn a non-Discourse messaging system on top of learning the Wolfram Language from scratch. I hope the community software is refreshed, but I really don’t expect anything to change. I have empathy for anyone who is confused by this idiosyncratic messaging software.

In the mean time, newbies will occasionally encounter the “updating name” bug and will get a confusing error message if they dare try to enter an emoji into the discussion. I fondly hope they ignore the “updating name” glitch and adapt to avoiding emojis – or use OG ASCII Art for their emojis. It’s definitely a First World Problem – maybe even a Zeroth World Problem. :wink:

1 Like

Absolutely, the local doc option - with live notebook pages! - is great. One improvement would be if the doc notebook window was tabbed so you could quickly flip between multiple ones. Or maybe it is and I just don’t know how to do it. (I do know about the tiny “history” downarrow.)

1 Like

I’ve never seen tabbed notebooks, but Documentation`HelpLookup[""] or Documentation`HelpLookup["SameQ"] will bring up a new, additional help notebook.

I’ve sometimes opened two help browsers by accident, too, just doing ordinary cmd-F or menu actions. I don’t why it sometimes does that. It doesn’t happen often. It may have been a bug in a particular version.

1 Like

One property that is slightly different in Equal and SameQ that will seem significant to people who program with floating-point numbers (Real objects) is that they compare with relative tolerance. Equal uses a greater tolerance than SameQ. Two numbers test as the same if they differ only in their last seven, resp. one, bit(s).

1. + (2^6) $MachineEpsilon == 1.
1. + (2^6 + 1) $MachineEpsilon == 1.
(*
True
False
*)

1. + $MachineEpsilon === 1.
1. + 2 $MachineEpsilon === 1.
(*
True
False
*)

To test if Real numbers are actually the same, I test the difference against zero: x - y == 0.

LessEqual, GreaterEqual also test with tolerance. So that x <= y can be true but x - y <= 0 will be false. Likewise, x <=y <= z can be true, but x <= z can be false.

1. + (2^6 + 1) $MachineEpsilon <= 1. + (2^6) $MachineEpsilon <= 1.
1. + (2^6 + 1) $MachineEpsilon <= 1
(*
True
False
*)

The tolerances are system parameters, Internal`$EqualTolerance (= Log10[2.^7]) and
Internal`$SameQTolerance (= Log10[2.]), that users can change. (Just because users can change it does not mean the system won’t reset it during an internal computation.) Compile[] has a runtime option "CompareWithTolerance" that controls it.

I once thought I could use MatchQ[x, y] to strictly compare Real numbers x and y. But no, MatchQ[] seems to do this: Round up x and y from a 53-bit mantissa to 52 bits and returns whether the rounded numbers are the same. This is undocumented, AFAIK, and I do not have an explanation for it.

MatchQ[1., 1. + $MachineEpsilon]
MatchQ[1. + $MachineEpsilon, 1. + 2 $MachineEpsilon]
MatchQ[1. + 2 $MachineEpsilon, 1. + 3 $MachineEpsilon]
(*
False
True
False
*)
2 Likes

There is a way to set up a tabbed interface – but only in a single Notebook. This 7-minute video shows how. IMHO, that would be incredibly convoluted way to be hacking your User Interface on the fly. I suppose you could create an empty Notebook with all of the scaffolding in place and reuse that as you grow new Notebooks. Alternatively, you could present your code to an AI and ask it to add the scaffolding – and hope the AI gets it right. In either case, Wolfram’s option really no substitute for an interface that allows to quickly flip between all Notebooks with tabs. Perhaps Wolfram Research will adopt a fully blown tabbed UI in the feature. BTW: I hadn’t realized that the history of documentation topics was available as a pull-down. That’s almost as good as tabs for the docs!

The way tabs work reveal a fundamental philosophy of the Wolfram Language. Someone immersed in the Wolfram Language could probably cobble these together in their muscle memory. It’s an incredibly capable system, but you need a certain criticality of information to wrap your head around it. There’s a big up-front investment, but it pays off in the end. On the flip side, Wolfram pays a penalty because their software is decidedly not friendly to new users. OTOH, I could imagine highly experienced users building those “tabs” solely with their muscle memory.

I noted that you can look up the full form of “==”, “@@@” and ALL the shortcuts easily by entering them in the documentation. You can also do that by simply saying:

FullForm[exp1 == exp2]

in the Wolfram Language itself. The App will tell you:

Equal[exp1, exp2]

The joker comes if you say:

FullForm[exp1 === exp2]

which simply returns:

False

At first blush, that’s really confusing. But you can get the “correct” result by saying:

FullForm[Hold[exp1 === exp2]]

Which returns:

Hold [SameQ [exp1, exp2]]

That’s better! I don’t this course ever explicitly talks about Hold – delay evaluation – but it does talk
about := (SetDelayed) and :> (RuleDelayed). Those are powerful design elements in the language. It’s really valuable to “have a play” with those ideas by diddling around in the Wolfram Language (as Rory has famously said in this course). Little Aha! moments is the keystone to thriving in this environment. I like to think it give you a way to touch the Great Minds that designed this machinery. It’s a beautiful design, but you must work a bit to understand and appreciate it. Sometimes, you don’t realize what you have learned until you try to teach it to others.

The Wolfram Language – Mathematica – has been available for 38 years. Stephen wrote about this back in 2018. He fired up an ancient (1986 - 1988 era) Mac, saved a notebook in Mathematica 1.0, then imported it to current Mathematica – Version 11.3 back in 2018 – and it just worked. That whole freakin’ blog article is about Stephen “having a play” on that early version of Mathematica running on an ancient Mac with 2.5MB (!!!) of RAM. You can almost hear the giddy excitement when he witnessed that ancient Notebook running correctly. Wow.

You can learn a lot about Wolfram’s priorities from the blog article. You can also learn the flip side: a tabbed interface hasn’t been a priority. Adopting the ubiquitous Discourse for user community discussions isn’t a priority. It is what it is. On another flip side, maintaining a free version of the Wolfram Language for the Raspberri Pi for the past 12 years is also mightily impressive. Wolfram Research has its priorities. I’m just curious if anyone on the inside pounds away for adopting Discourse for the community, or if they figure that’s not a battle worth fighting. I’ll end with another OG ASCII emoji: :slight_smile:

An EventHandler[] toy: 25 particles (circles) interact with each other. They eventually settle down into some sort of flow, with the occasional random circle deciding they like someone else. Click and drag to move one and upset the status quo.

DynamicModule[{
  n = 25, (* number of pts (constant) *)
  pts,
  drag = {} (* index of pt being dragged *)
  },
 pts = RandomReal[{-1, 1} 25/Sqrt[3 n], {n, 2}];
 EventHandler[
  Deploy@Graphics[ (* Deploy[] turns off the usual Graphics interactions *)
    Dynamic@GraphicsComplex[ (* efficient way to manage a figure that is a function of points *)
      pts = (* move[] the points, except the one being dragged *)
       ReplacePart[pts + move[pts], # :> MousePosition["Graphics"] & /@ drag],
      {Hue[#/n], Sphere[#, 0.7/Sqrt[n]]} & /@ Range[n]],
    PlotRange -> 25/Sqrt[n]
    ],
  (* mouse up/down: de/register which point is to be dragged *)
  {"MouseDown" :> (drag = Nearest[pts -> Automatic, MousePosition["Graphics"]]),
   "MouseUp" :> (drag = {})}
  ],
 Initialization :> ( (* define how the points move *)
   ClearAll[move];
   (* it returns changes in position for each point in the list p *)
   move[p_List] := Module[{$n, interaction},
     $n = Length[p];
     interaction = Array[
         Function[{row, col},
          Exp[-Abs[(row - col)/4] + 0.5 UnitStep[row - col] - 0.25]]
         , {$n, $n}
         ]/(IdentityMatrix[n] + DistanceMatrix[p])^2 // Function[mat,
        DiagonalMatrix[Total[mat] - 0.01 $n] - mat];
     0.2*(interaction . p)
     ];)
 ]

I would have posted a cloud notebook, but it didn’t render. Maybe Dynamic[] doesn’t work so well there?

Yikes! Spent quite a few hours yesterday wrestling with a DynamicModule problem (or at least I thought it was) before writing it up to ask the experts at mathematica.stackexchange.com. Whereupon I was almost immediately informed that a particular ; should have been a , and that was my entire problem.

Syntax counts! Even just a single dot! Code carefully!

(And of course this error has a lot to do with years of programming in languages that use ; as a separator or statement terminator, which is not the Wolfram Language way …)

(BTW Evaluation > Analyze Notebook seems useful but didn’t catch this error.)

Nice! Reminds me of this youtube channel: Alexander Gustafsson - these would be reasonable to set up in Mathematica (though I wonder how well it would scale interactively, you could certainly generate high quality videos)

Rory said carte blanche today that his Pacman-like video game will not run off of the cloud. If you looked at my cloud code showing Rope Flow under a monolith, the animation is quite squirrelly. The 3D cursor won’t change the perspective of the frame until you PAUSE the moving ball.

I am looking at using CDF (Computable Document Format) for deploying some code. It runs against the Wolfram Player, which is basically a read-only version of the Wolfram Language. Wolfram has de-emphasized this approach over the last few years, but it’s still viable. Apparently, users balked at downloading the multi-GB Wolfram Player.

Claude has some suggestions on how to make Dynamic viable. You can just put your whole block of code in and have Claude stick in its suggestions. Their code generation is much improved from 6 months ago.

This is a super little interactive example.