Ode to a Title
Oh sextant, let us punt! What concerning the outmoded bluntness you count.

What are examples of things I can create with randomness?

The following  is a little introduction to different ways of including randomness in art and text. For my students and me, this generated a lot of laughs. Though, beware, I cannot guarantee that all results will be completely school appropriate.

Art Background with Randomness

First, let’s create some randomly generated art using Graphics. We can generate a random set of coordinates with RandomReal and set it up as a primitive to be used within Graphics.

Point[RandomReal[{-10,10},2]]

We can assign a random color to the point.

{RandomColor[],Point[RandomReal[{-10,10},2]]}

Use Table to generate 100 points each with random coordinates and colors.

Table[{RandomColor[],Point[RandomReal[{-10,10},2]]},100]

To visualize these points, wrap the table with Graphics.

Graphics[Table[{RandomColor[],Point[RandomReal[{-10,10},2]]},100]]

Let’s make the points larger.

Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100]]

Now we can make an image using the Image function.

Image[Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100]]]

With an image, we can add effects. Here we will use a motion blur effect. The function ImageEffect takes the image as the first argument and the type of effect as the second argument. The value after “MotionBlur” indicates the strength of the blur.

ImageEffect[Image[
Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100]]
],{"MotionBlur",10}]

The direction of the blur can be set as an angle. Try a few different angles such as π/2, π/4, and 0.

ImageEffect[Image[
Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100]]
],{"MotionBlur",10,Pi/2}]

Pick an angle you like and increase the level of blur.

ImageEffect[Image[
Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100]]
],{"MotionBlur",100,Pi/2}]

The angle could even be random! Also, within Graphics, let’s set the image size to 400 for later.

ImageEffect[Image[
Graphics[Table[{RandomColor[],PointSize[0.04],Point[RandomReal[{-10,10},2]]},100],ImageSize->400]
],{"MotionBlur",100,RandomReal[{0,2Pi}]}]

What if the points are bigger? Change the value within PointSize.

ImageEffect[Image[
Graphics[Table[{RandomColor[],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],ImageSize->400]
],{"MotionBlur",100,RandomReal[{0,2Pi}]}]

I plan to put white text on this background, so I’m going to make it darker by darkening each random color.

ImageEffect[Image[
Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],ImageSize->400]],{"MotionBlur",100,RandomReal[{0,2Pi}]}]

What about random words?

Note that usually when we want to work with text, we use “quote marks” around the text to make it a string.

"hello"

Two or more strings can be combined into a single string using StringJoin.

StringJoin["Hello","world!"]

Oops! Let’s include a space either at the end of hello or beginning of world.

StringJoin["Hello ","world!"]

Note that StringJoin may also take a list of strings as input.

StringJoin[{"Hello ","world!"}]

We can retrieve a random word from the Wolfram Language WordList using RandomWord.

RandomWord[]

Random words may also be retrieved for specified parts of speech.

RandomWord["Adjective"]

To create a random sentence that may actually read like a sentence, let’s start with an actual sentence.

"The black cat sits quietly on the large box."

We can rebuild this sentence using StringJoin while replacing some of the words with random words of the same part of speech.

StringJoin["The black ",RandomWord["Noun"], " sits quietly on the large ",RandomWord["Noun"],"."]

Let’s replace some more of the words.

StringJoin["The ",RandomWord["Adjective"],RandomWord["Noun"],RandomWord["Verb"],RandomWord["Adverb"]," on the ",RandomWord["Adjective"],RandomWord["Noun"],"."]

Don’t forget the spaces. Here we need to insert spaces as their own strings between the random words.

StringJoin["The ",RandomWord["Adjective"]," ",RandomWord["Noun"]," ",RandomWord["Verb"]," ",RandomWord["Adverb"]," on the ",RandomWord["Adjective"]," ",RandomWord["Noun"],"."]

The verb doesn’t seem to fit well after the noun. An option for RandomWord is to include inflections, so let’s try this for the verb. It will help some, though not always.

StringJoin["The ",RandomWord["Adjective"]," ",RandomWord["Noun"]," ",RandomWord["Verb",IncludeInflections->True]," ",RandomWord["Adverb"]," on the ",RandomWord["Adjective"]," ",RandomWord["Noun"],"."]

What if we want to alter even more words? How can we identify those parts of speech? Use TextStructure.

TextStructure["The black cat sits quietly on the large box.","PartsOfSpeech"]

What kinds of words are prepositions?

RandomWord["Preposition",20]

If you ask for enough random prepositions, you will see some repeat. How many are there?

Union[RandomWord["Preposition",1000]]//Length

What kinds of words are determiners?

RandomWord["Determiner",20]

How many are there in WordList?

Union[RandomWord["Determiner",1000]]//Length

So if we replace everything, we get something like this.

StringJoin[RandomWord["Determiner"]," ",RandomWord["Adjective"]," ",RandomWord["Noun"]," ",RandomWord["Verb",IncludeInflections->True]," ",RandomWord["Adverb"]," ",RandomWord["Preposition"]," ",RandomWord["Determiner"]," ",RandomWord["Adjective"]," ",RandomWord["Noun"],"."]

Clearly some additional work would need to be done to smooth out the grammar a bit.

Ode

I found that random word generation is more fun when there is more fixed structure to the output. I put the following together as a mini-ode generator.

StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}]

In fact, I evaluated this a few times looking for inspiration for an activity title and the following appeared. Perfect!

Create your own text generator that makes something you find fun. Are there other parts of speech you could try to include?

RandomWord["Interjection",100]

Check the Documentation for additional parts of speech that work with RandomWord.

Add Some Style

Use the Style function around your text generator to give it some flare and to make the text larger so we can combine it with the background we made earlier.

Style[StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}],
30,Bold,Italic,Blue,FontFamily->"Times"]

To make it fit well in our work of art, we want to restrict the width of the text. Pane will set the pixel width of a boundary that contains the text.

Pane[Style[StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}],30,Bold,Italic,Blue,FontFamily->"Times",LineIndent->None],325]

A Random Masterpiece

Now we will put it all together. Get the code from the background graphics and give it a name (art) and get the code from the text generator and give it a name (words). We can evaluate both at the same time.

art=ImageEffect[Image[
Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],ImageSize->400]],
{"MotionBlur",100,RandomReal[{0,2Pi}]}]

words=Pane[Style[StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}],30,Bold,Italic,Blue,FontFamily->"Times",LineIndent->None],325]

To put it all together in one piece, we will use Overlay.

Overlay[{art,words}]

Ah, but we need to fix a few things.
Have everything together in one cell so all of the randomness will regenerate each time.
Put a semi-colon ;  after the definition of art and also after the definition of words.
Change the font color to White.
Include the Alignment option for Overlay.
And we’ll give our overlay art a frame using Framed with a black background.

art=ImageEffect[Image[
Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],ImageSize->400]],
{"MotionBlur",100,RandomReal[{0,2Pi}]}];

words=Pane[Style[StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}],30,Bold,Italic,White,FontFamily->"Times",LineIndent->None],325];

Framed[Overlay[{art,words},Alignment->Center],Background->Black]

An example is below.

Option: Adjust the Graphics

If you have large points, the plot range of the graphics extends beyond the domain of random coordinates for the points. When the motion blur is added there is more whiteness around the edges than in the middle.

Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],ImageSize->400,Axes->True,AxesStyle->White]

We can set the PlotRange to match the domain of the random points.

Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],PlotRange->10,ImageSize->400,Axes->True,AxesStyle->White]

Now the motion blur is less likely to have any white. Also, we can reduce the value of the Darker colors.

art=ImageEffect[Image[
Graphics[Table[{Darker[RandomColor[],0.3],PointSize[0.4],Point[RandomReal[{-10,10},2]]},100],PlotRange->10,ImageSize->400]],
{"MotionBlur",100,RandomReal[{0,2Pi}]}];

Framed[Overlay[{art,words},Alignment->Center],Background->Black]

Other adjustments could be to add more points and make them smaller. Also, let’s increase the level of blur. (Note that I set the Darker level higher again.)

art=ImageEffect[Image[
Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.1],Point[RandomReal[{-10,10},2]]},200],PlotRange->10,ImageSize->400]],
{"MotionBlur",200,RandomReal[{0,2Pi}]}];

Framed[Overlay[{art,words},Alignment->Center],Background->Black]

Instead of a motion blur, we can use a regular blur. Change ImageEffect to Blur and replace the effect details with a level of blur. I suggest increasing the number of points as well to have less whitespace in the background.

art=Blur[Image[
Graphics[Table[{Darker[RandomColor[],0.6],PointSize[0.1],Point[RandomReal[{-10,10},2]]},1000],PlotRange->10,ImageSize->400]],
10];

Framed[Overlay[{art,words},Alignment->Center],Background->Black]

Of course we can use lighter colors too. Change Darker to Lighter and adjust to a desired level. You will probably want to change the font color to Black if you use a lighter background. Let’s randomize the point size as well.

art=Blur[Image[
Graphics[Table[{Lighter[RandomColor[],0.5],PointSize[RandomReal[{0.01,0.25}]],Point[RandomReal[{-10,10},2]]},500],PlotRange->10,ImageSize->400]],
10];

words=Pane[Style[StringJoin[{"Ode to a ",Capitalize[RandomWord["Noun"]],"\nOh ",RandomWord["Noun"],", let us ",RandomWord["Verb"],"! ","What ",RandomWord["Preposition"]," the ",RandomWord["Adjective"]," ",RandomWord["Noun"]," you ",RandomWord["Verb"],"."}],30,Bold,Italic,Black,FontFamily->"Times",LineIndent->None],325];

Framed[Overlay[{art,words},Alignment->Center],Background->Black]

The example below popped up while I was experimenting and I thought its title made it worth keeping.

Option: Convert to an Image

If you would like to convert the final product to an image, one way to do that is to export the result to a .jpg file (or another image file type) and then import that result.

Import[Export["img.jpg",Framed[Overlay[{art,words},Alignment->Center],Background->Black]]]

To have a higher quality image, increase the ImageSize in Export. However, to view it smaller within your notebook, use Style and Magnification to reduce the displayed size.

Style[Import[Export["img.jpg",Framed[Overlay[{art,words},Alignment->Center],Background->Black],ImageSize->800]],Magnification->0.5]

Option: Extract Parts of Speech from a Sentence to Build a New One

Above we saw that the Wolfram Language can identify parts of speech of words within a sentence. In fact, it can represent the complete grammatical structure of a sentence.

TextStructure["The black cat sits quietly on the large box."]

Or try this.

TextStructure["The black cat sits quietly on the large box.","DependencyGraphs"]

At first I tried the PartOfSpeech function directly.

PartOfSpeech["sits"]

However, I quickly saw why this would not work for what I had in mind.

Map[PartOfSpeech,TextWords["The black cat sits quietly on the large box."]]

We need to get the specific parts of speech that match the words as in the context of our sentence. Let’s go back to TextStructure for identifying parts of speech and give that result a name. (I will use “pos” for Parts Of Speech.)

pos=TextStructure["The black cat sits quietly on the large box.","PartsOfSpeech"]

Everything in the Wolfram Language is built from functions. There must be some underlying structure here from which we can extract the parts of speech in order.

FullForm[pos]

The double bracket [[  ]] shortcut for Part will let us pull out parts of functions at various levels. With a little digging, I was able to figure out that the following gives me close to a list of the parts of speech in order.

pos[[1,1,1,All,2,All,2]]

What we see here is a list of associations. We want to get the value of the element in each association.

Values[pos[[1,1,1,All,2,All,2]]]

Getting closer. Flatten will get rid of the internal layer of lists.

Flatten[Values[pos[[1,1,1,All,2,All,2]]]]

In my exploration I found that RandomWord cannot generate punctuation, so we will want to delete any of those cases.

parts=DeleteCases[Flatten[Values[pos[[1,1,1,All,2,All,2]]]],"Punctuation"]

Now we can find random words of each of these types.

Map[RandomWord,parts]

And we can join them together to make a sentence.

StringJoin[Map[RandomWord,parts]]

Oops! We need spaces again. Check out the function Riffle.

Riffle[{1,2,3,4},x]

We can use this to insert a string of a space between each of the random words before using StringJoin.

StringJoin[Riffle[Map[RandomWord,parts]," "]]

Within the StringJoin we can add a random punctuation mark.

StringJoin[Riffle[Map[RandomWord,parts]," "],RandomChoice[{".","?","!"}]]

Use capitalization to make it look more like a sentence.

Capitalize[StringJoin[Riffle[Map[RandomWord,parts]," "],RandomChoice[{".","?","!"}]]]

Put it all together so we can easily change the generating sentence and see results.

pos=TextStructure["The black cat sits quietly on the large box.","PartsOfSpeech"];
parts=DeleteCases[Flatten[Values[pos[[1,1,1,All,2,All,2]]]],"Punctuation"];
Capitalize[StringJoin[Riffle[Map[RandomWord,parts]," "],RandomChoice[{".","?","!"}]]]

Try another sentence. Does the structure match?

pos=TextStructure["Computational thinking is interesting and fun!","PartsOfSpeech"]
parts=DeleteCases[Flatten[Values[pos[[1,1,1,All,2,All,2]]]],"Punctuation"];
Capitalize[StringJoin[Riffle[Map[RandomWord,parts]," "],RandomChoice[{".","?","!"}]]]

Abby Brown
www.abbymath.com
CT@TP: Computational Thinking at Torrey Pines High School
November 2018