Alvin Alexander | Java, Scala, Unix, Perl, Mac OS X

Without an example it can be hard to understand how user authentication works in a Play Framework application, so I just created a project on Github named PlayFrameworkLoginAuthenticationExample that demonstrates one way to implement login authentication in a Play Framework 2.6 application.

On April 22, 2018, the Mosaic web browser — the internet’s first major web browser — turned 25 years old. And I’m old enough to remember using it. (Image from this tweet.)

The Mosaic web browser turned 25

As a quick note, here’s a Java method that will round a float to the nearest half value, such as 1.0, 1.5, 2.0, 2.5, etc.:

 * converts as follows:
 * 1.1  -> 1.0
 * 1.3  -> 1.5
 * 2.1  -> 2.0
 * 2.25 -> 2.5
public static float roundToHalf(float f) {
    return Math.round(f * 2) / 2.0f;

The comments show how this function converts the example float values to their nearest half value, so I won’t add any more comments here.

From a recent email:

Paraprosdokians are figures of speech in which the latter part of a sentence or phrase is surprising or unexpected; frequently humorous. Winston Churchill loved them.
1. Where there's a will, I want to be in it.
2. The last thing I want to do is hurt you. But it's still on my list.
3. Since light travels faster than sound, some people appear bright until you hear them speak.
more ...

“Complaining is not a strategy. You have to work with the world as you find it, not as you would have it be.”

~ Jeff Bezos

If you struggle to learn new things, check out this podcast interview with Barbara Oakley. A few years ago I read her book, A Mind for Numbers: How to Excel at Math and Science (Even If You Flunked Algebra), and it was helpful to me, and even influenced my book, Functional Programming, Simplified.

As I noted five days ago, Mollom went out of business so I had to switch this Drupal 8 website to use a different module to control comment spam. I ended up adding two modules that work together, but the side effect of using their best features is that they end up disabling Drupal 8 page caching. This image clearly shows the result that disabling page caching has on CPU use.

Disabling Drupal 8 page caching significantly increases CPU use

“People have a voracious appetite for a better way, and yesterday’s ‘wow’ quickly becomes today’s ‘ordinary.’”

~ Jeff Bezos, Amazon, in his 2017 (2018?) letter to shareholders

In a slightly related note I find that work is easier when you have the attitude that what you’re working on is constantly changing, constantly evolving. If one day you think, “There it is, Product 1.0, I’m done,” you’ll find it mentally hard to come into the office tomorrow to work on the same product. The only constant is change, and if you accept that your job is to be in that process of change, life and work are easier.

As shown in the image, the project known as Dotty will be Scala 3.0.

Dotty will become Scala 3.0

It’s kind of neat when you get royalty checks in multiple currencies. :)

(But one drawback to receiving physical checks is that most tellers here don’t know what to do with them. Each time I’ve received checks in foreign currencies it’s taken 15-30 minutes to deposit them at the local bank.)

Royalty checks in multiple currencies

This is a good quote from the tv series, Hart of Dixie. I remember when I thought about selling my business I knew I might regret it, but I also knew that I was sick with something and doctors couldn’t figure out what it was. So I decided to sell the business and move to Alaska, and that was one of the best decisions of my life. I got to experience things that won’t even be possible to experience in the future because roads are being paved, civilization keeps encroaching on nature, and global warming is melting the glaciers and polar bears into extinction. In retrospect I’d make that decision 100 times out of 100.

A life without regret ain't worth living

I like both parts of this tweet. I try to help other people where I can, but in the end you can’t take responsibility for what the other person does or doesn’t do.

Peace requires us to surrend our illusions of control

I just bought a bunch of MP3 music files from Amazon, and when I downloaded the zip file they provide onto my Mac, it was a bunch of files in a bunch of subdirectories; not really convenient to work with when you’re trying to import them into iTunes. So I used this Unix find command to move all of the music files from the subdirectories they were scattered in into the root directory that was created when I expanded the zip file:

cd Amazon-Music-Folder
find . -type f -exec mv {} . \;

If you ever need to either copy or move a bunch of files with a single command, I hope this example shows the correct find command syntax for your needs. (If you need to copy the files, use the cp command instead of the mv command.)

Table of Contents1 - Anorm2 - More background ...3 - A note about my coding style4 - SQL SELECT queries5 - A brief intermission6 - SQL INSERT with primary key (auto increment)7 - SQL INSERT with no primary key8 - SQL UPDATE9 - SQL DELETE10 - Complete example methods11 - A complete class12 - More information

In general the online Play Framework documentation is excellent, but one area where I needed more help was in seeing more examples of the Anorm syntax. To that end, here are some Anorm query examples, taken from a Play Framework application I worked on recently. But first, a little background about Anorm.

One thing I never thought about before is that if you need to get multiple, unique, random elements from a list of elements, one solution to the problem is to shuffle the list and then take as many elements as you want/need. For instance, if you want three unique, random elements from a list of integers in Scala, you can do this:

scala> val list = List(1,2,3,4,5,1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)

scala> val uniq = list.distinct
uniq: List[Int] = List(1, 2, 3, 4, 5)

scala> val shuffled = scala.util.Random.shuffle(uniq)
shuffled: List[Int] = List(1, 4, 5, 2, 3)

scala> val firstThree = shuffled.take(3)
firstThree: List[Int] = List(1, 4, 5)

As that solution shows, you start with a simple list; get the unique/distinct elements from the list; shuffle those elements to create a new list; then take the first three elements from the shuffled list. That’s probably not a great solution for huge lists, but for many simple lists it’s a way to get multiple random elements from the list.

I’m not sure why, but on April 3, 2018, the people behind the Mollom anti-spam module for Drupal basically went out of business. This meant that I either had to disable comments on this site (which I did for a while), or look at other anti-spam modules, which I did over the weekend.

Drupal 8 - enabling anti-spam modules is bad for performance

While this photo looks like a sunset, it was actually a sunrise. I took it in Virginia Beach on April 17, 2017.

Dark sunrise, Virginia Beach

“Do I look like a guy who needs hookers?” is going right between “We choose to go to the moon...” and “Mr. Gorbachev, tear down this wall” in my list of great presidential quotes.

If you’re interested in learning about “pay for written content” models, Medium has an article titled, The Medium Model
How we are building a system for high-quality publishing at scale