A recommended JavaScript learning resource

Though my last post was about FasterPay, I want to point out the eBook seller using that service was actually really great when I wrote to inform him about the situation. It’s a shame he operates in a region where his eCommerce options are limited.

So I wanted to give a shout-out about his site (javascript.info) is actually a really good tutorial on JavaScript, translated into several other languages (Japanese, Korean, Chinese, Turkish and Russian) by native speakers. This aspect attracted me to his content, as I’m learning Japanese and wanted some technical Japanese material to study. In any case, I wholeheartedly recommend you check out his tutorial site.

A warning about FasterPay

FasterPay is a relatively newcomer to the payment processing scene. I used it to purchase a software-development ebook. The merchant offered FasterPay as a PayPal alternative that accepts Visa or MasterCard. I gave it a go, but wish I hadn’t. When I got my credit card statement, I noticed the issuing bank had added a 16% cash-advance fee (on top of the usual forex and overseas transaction charges) and a cash-advance interest fee. Curious about this, I called my bank and I asked about the seller’s merchant code. The merchant code (MCC) is an important piece of data for the banks. It allows them to classify purchases since the narrative (the short one-liner of text that accompanies your transaction shown on the bill) may not give enough detail. A four-digit merchant code can be looked up to give info about the business the merchant is conducting, and potentially allow the issuer to block or impose a condition on a transaction. In my case, the FasterPay transaction’s MCC was 6051 (i.e. Non-Financial Institutions – Foreign Currency, Money Orders (not wire transfer) and Travelers Cheques). So the issuing bank considers it a cash equivalent, and can levy cash-advance fees. This is pretty weird for an ebook on a programming language.
My issuing bank considers a use case for this code as cash-equivalent purchases, like gaming. So be aware of this processor. Due to the MCC and fees, it may be a good idea to avoid unless you have no choice.

Red Parse: simple rules

In the last post, I introduced a very simple find-and-replace in parse.

Let’s refactor this a bit to set some rules and in doing so, make this code more readable.

So we had this:

s: "this is a fantastic day"
parse s [to "fantastic" change "fantastic" "great"]

which replaces one instance of “fantastic” with “great”.

We could break down the rules above into:

key-word: "fantastic"
my-find: [to key-word]
my-replace: [change key-word "great"]
parse s [my-find my-replace]

This will help make the parse part a little more readable or understandable.

When run in the REPL, this will result in s being updated to:

== "this is a great day"

The readability comes about by creating rules for my-find and for my-replace. Each rule is placed in square brackets or a block. Without the brackets, you’d get an error.

Because parse evaluates rules from left to right, the first rule my-find is evaluated first, and if successfully evaluated, then parse moves onto my-replace.

It’s possible to make the code perhaps a little more elegant by:

do-this-action: [my-find my-replace]

and then parse becomes:

parse s do-this-action

You get the idea.

This concept of setting up granular rules will greatly help maintain clarity and maintainability as you write your own parsing routines.

Red’s Parse dialect

I’ve started to explore the Red programming language (based on Rebol) as an alternative to Python for some text-processing applications.

Red contains its own text-processing dialect called Parse. It’s rather fascinating as it does away with regex, and instead offers a rules-based method for searching text. I’m still exploring the basics. In this short article, I’ll summarise some of my understanding.

To follow along, you’ll need to install Red, which comes with its own REPL and compiler all built into one convenient exe for Windows, Mac or Linux.

Simple search and replace

Open up the REPL, and specify a string simply by typing the variable name followed by a colon, then the string in quotes.

s: "this is a great day"

upon pressing enter, the REPL will echo the string

== "this is a great day"

To search for “great” and replace it with “fantastic” use the parse keyword:

parse s [to "great" change "great" "fantastic"]

If you then print the value of s, you’ll see:

>> print s
this is a fantastic day

So how does this work?

Firstly, parse is the keyword command to do some parsing. It takes two parameters: the string to evaluate and a block containing rules. Blocks are encapsulated with square brackets. At the start of the parse, the string pointer is at the head of the string.

Rules are executed and evaluated from left to right. So where are the rules? Rules are specified and supplied in a block as parse’s second parameter, as indicated by the coloured regions below:

The first rule (in blue) means ‘advance the pointer until “great” is found, and then put the pointer at the start of the found string’, i.e.:

Then the next rule (in pink) is evaluated. Now, look for a match on “great” which is possible since the pointer is at the start of “great”, and then replace that content with “fantastic”. This gives the result as shown before:

this is a fantastic day

This of course works for contracting a string:

s: "this is a fantastic day"
parse s [to "fantastic" change "fantastic" "slack"]
print s
this is a slack day

Removing or altering a duplicate word

Replacing to to thru performs the same search but changes the pointer position as a result of a match. Consider the following:

s: "this is a greatgreat day"
parse s [thru "great" change "great" " and fantastic"]
print s
this is a great and fantastic day

This works since thru places the pointer after the match, like so:

It can be seen that rules can be chained, so that the following should be possible:

However if you run this, you’ll get the unexpected result of:

this is a great and fantastic day

lacking the change from “day” to “event” because after the second rule is done, the pointer is actually positioned here:

so the last rule matching “day” will fail at that point since the pointer is on the space.

There are two solutions:

parse s [thru "great" change "great" " and fantastic" change " day" " event"]

or the more elegant one:

parse s [thru "great" change "great" " and fantastic" skip change "day" "event"]

where a skip rule is added before the last change request.

which produces the expected result:

this is a great and fantastic event

Skip advances the pointer by one character, so the subsequent rule seeking a change on an immediate match of “day” will succeed and the change can occur.


Some simple find-and-replace examples using Red’s Parse were shown. Admittedly, these have limitations (like only the first match is found in a string) and these examples are probably overkill for parse (i.e. other Red keywords are better suited). These examples simply show the basic rules-based nature of Parse, which makes for readable code and powerful text-processing. I hope to write up some more experiences in the near future.

Windows 10: how to fix lost wireless connection upon waking computer from sleep

Do you find it annoying that your Windows 10 PC forces you to reconnect your wireless upon awakening your PC from sleep? Yes it’s a rather annoying default setting that doesn’t make a lot of sense. When the PC wakes up, it should reconnect automatically. There are at least a couple of solutions.. you could prevent your computer from going to sleep, or you can disable the network adapter from participating in the sleep event. I’ll show the solution using the latter method.

Firstly, locate the network adapter properties. There are a few ways to do it – I think the easiest way is via Device Manager. Right-mouse click the Start icon and select Device Manager. Then locate Network Adapters and then expand (click on the triangle) and right-mouse click the relevant device (probably the wireless one) similar to the following figure:



Then click the Power Management tab, and uncheck the Allow the computer to turn off this device to save power, and click OK.



That’s all!

Advice for starting a mobile app business

In short, two things: (1) register your sole-trader or similar business entity for tax purposes, and (2) close the Apple contract for paid apps. If you have a decent app idea, do these things as soon as you start development. Apple require developers to show evidence they are registered for local tax before allowing them to sell apps on the app store.
Continue reading

Getting Godot Engine to display Japanese

The game-making system Godot Engine is interesting, and has caught my eye. I’m interested in creating games for English and Japanese markets, so non-Latin character support is a must for me. The system appears to support Latin by default. The current docs for setting up and working with non-Latin characters is a bit scant, so here’s some of my findings.

Continue reading

Overcoming issues attaching SQL Server database files

I’m doing some reporting work against a SQL Server database, and received some files (a .mdf and .ldf file) for evaluation. Starting from scratch with no version of SQL Server installed, the first thing to confirm was: exactly what SQL Server database was used to create these files? There’s no straight-forward way to determine version. It seems the best way is to inspect the .mdf file with a hex editor, go to the location 0x12064, read the 2 bytes there, and convert to decimal.

Hex values

Continue reading

New year, new desk

As you’ve undoubtedly heard, sitting at desk is akin to the “new smoking”, i.e. long-term sitting is thought to be not good, and could lead to issue down the track. For me personally, I’ve found it’s hard to maintain a good posture while seating (despite my best intentions and efforts). So this year I opted to try a stand-up desk. Fortunately I have an old Ikea Jerker desk which is very configurable. Ikea discontinued this desk several years ago. The table area itself can be raised to virtually any height. I now have a bar chair, which is easy to move in or out as needed. I often start the day standing, and try to stand for as long as possible before bringing the chair back in. So far, I’ve found for periods requiring concentration, I tend to prefer sitting. Let’s see how it goes..