javascript diversions

I started making a JavaScript quiz in October 2020 and it is still a work in progress. I finished reading an encyclopaedia from the 80s around then. I had for years been putting terms from the dictionary, the encyclopaedia, and to a lesser extent interesting trivia facts into three exercise books. The oldest book is almost full; the other two have gaps in them between randomly arranged terms. I am still typing up terms.

I started making the quiz with data in an external JavaScript (not quite json) file. Over time I divided the data into four categories; general, people, place, and dates. As I progressed I made the mechanics of the quiz programming ever more complicated, basically in an attempt to make the three wrong answers that appear with the correct option more relevant to the answer and question. For example, I added tags to the term data so they can be grouped.

I added some regular expressions (RegEx), which I am by no means expert at; there is a lot of trial and error involved.

I went as far as adding two RegEx to test matches which have gendered words (i.e. he|him|man|father and her|she|woman|mother). Surprisingly it works rather well. There aren’t that many questions like that but it was obvious when the question mentions “she danced” that any male name will be wrong. The RegEx fixes that because I have a tag for female anwers. Unfortunately there are many more men than women in the data. This is a bias inherited from history and my sources.

I also added a RegEx that matches a person’s name occurring in a question so that name can be rejected. I don’t want a question that includes Shelly in it to have an option of Shelly as an answer, for instance, as that would clearly be a wrong answer.

It took a while to establish that Unicode characters, e.g. é, are treated differently to ascii. For instance the matching of a word boundary that is achieved with a b treats the é character as a word boundary. This means that when I wanted to check a name like Frédéric the RegEx would treat it as including “Fr”, “d”, and “ric” as small words. I thought for a while the solution was to use the /u (Unicode!) modifier and avoid b usage. p{L} can be used to match a Unicode or ascii character. I believe the L stands for Latin.

Next I replaced the Unicode modifier with a character set of [a-zIVXS]. The Roman numbers turn up as numerals in pope names and S appears in St for saint. The expression was something like
/(^|s)(?!Sir|van|de|di)[a-zIVXS]{1-3}(s|$)/
which was getting unwieldy but kind of worked. Currently I match words that should be matched instead of looking for exclusions:
/s((the|of)s|[IVX]{1,4}$)/

Just to make the exercise more interesting I also created code that for a person with year of birth in brackets as the start of their question that will add a year based on the middle of their life if I can determine it. I then add a century from that year as a tag. With the tag and the year I can choose wrong answers that are close to the right time frame first. Mythical characters and a few people do not have a year.

 

As far as checking that a sequence of letters is an English word, as needed for Scrabble or anagrams, I found a regular expression with every English word in it! The file is about 2 Mb and doesn’t open safely in my editor, Netbeans, as it says the file is too big and may make the IDE unstable. I used Notepad to edit the structure to allow me to access it with my code. Testing a single word like “cat” takes multiple seconds and causes Chrome to pause. In other words as a RegEx it is totally unusable.

I investigated changing the RegEx to a string that is stepped through (pipe characters separate the words) as a way to create a lookup structure. Trie is one data type that consists of a branching structure of a node for every letter and an indicator of some sort that there is a termination, in other words, a longer word does not exist starting with that stub of letters. Trie has three basic operators; add, search, and remove. I thought Trie was overkill for my purposes. There is now a built in JavaScript data type called Map. Amongst other functions it has instance methods of set() and has().

Once I found it, I settled on the even simpler data type of Set that has methods of add() and has().

It only takes some milliseconds to add all the words in the string to a Set. It only takes a couple of milliseconds to find out if a word is in the Set. I won’t ever be making a Scrabble game as that has been done already and better than I ever could. You can though see the English Set in use in the diversions ANAGRAM7 and ANAGRAM8.

 

On 5 February 2021 it occurred to me how to make a programmable mask in JavaScript! To give my secrets away: the trick is to create the mask shape in one off canvas imageData alpha channel and copy it to the canvas imageData that is part of the document. First I made a circle that reveals a background image as you drag your finger (mouse). This was way easy to do back in the days of Director! Next I made a kaleidoscope. I made one without masking then one with reflected sectors that are masked.

This month, July 2021, I revisited the masking and made new programmatic animations adding masks created by changing vector shapes over random additions of lines and sinuous lines that look like my recent paintings. Check them out! I added some videos to YouTube too but I prefer the creation unfolding in real time.

Log in to write a note
July 16, 2021

I was happy when I mastered HTML. I was the first in my college class to have a website. 🙂 You should have seen my glee when I put in a guestbook on my page! LOL!!!

July 16, 2021

@kartoffeltorte I was an ActionScript programmer until Steve Jobs refusing to allow Flash on Apple killed Flash. My HTML and CSS skills are limited to achieving small goals like presenting my js multimedia and having sliders control some aspect of it.

Haha! your guestbook glee was probably matched by mine when I changed the size of my media on the mobile with a css media query.

July 17, 2021

@jiggered 😀💯