What Regular expressions:

Regular expressions are ways to describe a piece of text(sequence of characters), in a way that a regular expression engine could understand.

Existing/Possible use cases of regular expressions:

  1. Finding information by specifying minimal text: For example in the ‘Find’/‘Find all’/‘Replace’/‘Replace all’ functionalities in text editors and in formulation of search queries in text-based search engines.
  • Possible use cases:
    • I have known that negative thoughts detrimental for mental health follow a template. Can that template be expressed as a regex? Could that be used to detect negative thoughts in real time and help rewire thinking patterns?
    • If we convert music written by composers like Beethoven into a seuqneece of chords, can we express that sequence as a composer-specific regex or at least find recurring patterns?
  1. Generating information from templates:
  • Possible use cases: Create a poem/haiku/songs/rap/puzzle/motivational-quotes from a regex template?
  1. Converting across text-based file types: To parse information and convert across mutliple file types, like, converting an age-old Shakespeare sonnet into an XML file for better processing.
  • Possible use case: Generate a good pdf-parser, which is hard to find!
  1. Approximate string matching:
  • For problems like spell checking, matching neucleotide sequences and spam filtering.
  1. Determining data quality
  2. Classifying text based on presence of matches with a regex:
  1. Checking against standard data formats: SSN/Credit card/password format checkers.
  2. Augmenting neural networks

Assignment2 statement

Design an exercise around regular expressions.

My attempt: ‘Poetry Shuffler – Causing chaos with poetry’

This is what the final code looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
poem="\
I am in a course,<br>\
called programming A to Z,<br>\
\(uptil now\) I have no remorse,<br>\
it\'s been all fun and glee,<br>\
creativity it does endorse,<br>\
to that i shall agree,<br>\
and when the time comes for divorce,<br>\
i\'d have hopefully become artsy,<br>\
"
poem_element = null
selected_words_force = []
selected_words_bee = []
selected_words_all = []
repl_index = -1
rhyming_words_force = null
rhyming_words_bee = null

function reset_word_arrays(){
selected_words_force = []
selected_words_bee = []
selected_words_all = []
repl_index = -1
let spans = selectAll('span')
for(var i=0;i<spans.length;i++){
spans[i].style('background-color','white')
}
}

function replacerFun(match,sentence){
//TODO: how to replace dynamically
//on one one based on the group index
repl_index += 1;
return sentence + ' ' + selected_words_all[repl_index] + ',<br>'
}

function showOriginal(){
reset_word_arrays()
poem_element.html(poem)
}

function causeChaos(){
reset_word_arrays()
for(var i=0;i<4;i++){
//Math.random() will never be 1
selected_words_all.push(rhyming_words_force[Math.floor(Math.random()*rhyming_words_force.length)]); selected_words_all.push(rhyming_words_bee[Math.floor(Math.random()*rhyming_words_bee.length)]);
}
showPoem()
}

function showPoem(){
poem_copy = poem
//poem_copy.replace()
if(selected_words_force.length == 4 && selected_words_bee.length == 4){
for(const i in selected_words_force){
selected_words_all.push(selected_words_force[i])
selected_words_all.push(selected_words_bee[i])
}
} else if (!(selected_words_all.length == 8)){
alert('Please select words first!')
return
}
regex = /([a-zA-Z ]*)[ ]([a-zA-Z]*),<br>/gi
poem_copy = poem_copy.replaceAll(regex, replacerFun)
poem_element.html(poem_copy)
reset_word_arrays();
}

function selectRhymingWord_force(){
if(selected_words_force.length == 4) return
this.style('background-color','yellow')
//using this.html() since .value() is undefined
selected_words_force.push(this.html())
}

function selectRhymingWord_bee(){
if(selected_words_bee.length == 4) return
this.style('background-color','green')
selected_words_bee.push(this.html())
}

function setup() {
noCanvas();
createP('Pick four words that rhyme with force:')
//rhymes with a limit always returns the same words
//so get all first, and then use random() js method for arrays
rhyming_words_force = RiTa.rhymes('force',{limit: Number.MAX_SAFE_INTEGER})
for(const i in rhyming_words_force){
temp = createSpan(rhyming_words_force[i])
temp.mousePressed(selectRhymingWord_force)
if( i != rhyming_words_force.length - 1) createSpan(' , ')
else createSpan(' .')
}

createP('Pick four words that rhyme with bee:')

rhyming_words_bee = RiTa.rhymes('bee',{limit: Number.MAX_SAFE_INTEGER})
for(const i in rhyming_words_bee){
temp = createSpan(rhyming_words_bee[i])
temp.mousePressed(selectRhymingWord_bee)
if( i != rhyming_words_bee.length - 1) createSpan(' , ')
else createSpan(' .')
}
createSpan('</br>')
b = createButton('Write me a poem')
b.mousePressed(showPoem)
createSpan('<br>OR<br>')
r = createButton('Cause Chaos')
r.mousePressed(causeChaos)
createSpan('<br>OR<br>')
o = createButton('Show the original')
o.mousePressed(showOriginal)
poem_element = createP('')

}

function draw() {
background(220);
}

Things I learnt along the way:

  1. I can write a poem anywhere and anytime.
  2. p5js selectAll method can be used to pick all p5Elements of a particular type.
  3. One way to reset the background-color of an element over a white canvas, is to set it to white.
  4. Any global arrays that are being modified by a method (which could be called multiple times), need to be reset once that method is finished working, and in some cases, before it even starts.
  5. Random number picked using Math.random() would never be 1. Hence <length of an array>*Math.random() is the correct qay to randomly pick an index from an array.
  6. When using replaceAll method with a regex, need to append gi at the end of the regex, or you see the following error: TypeError: String.prototype.replaceAll called with a non-global RegExp argument.

Open Questions:

  1. How does RiTa find rhyming words? Why does it not consider pores to rhyme with force?

Improvements that can be done to this:

  1. As always, the design. The green is really pricking my eyeballs. And the whole layout seems lifeless.
  2. This includes a poem template on which few modifications are made. Can we possibly generate an entirely new poem on the fly?

Takeaways:

  • The only limit to creativity is your imagination .. and your mood schedule.

Demo: