Categories
Meetups Programming Tampa Bay

Building a “Wordle” function, part 1

These slides capture what we worked on Tuesday night’s “Think Like a Coder” meetup: coming up with a first attempt at a “Wordle” function. Given a guess word and a goal word, it should output a Wordle-style score.

We came up with a solution that I like to call the “close enough” algorithm. It goes through the guess word one character at a time, comparing the current guess word character with the goal word character in the same position.

When making those character-by-character comparisons, the function follows the rules:

Here’s the “close enough” algorithm, implemented in Python…

def wordle(guess_word, goal_word):
    
    # Go through the guess word one character at a time, getting...
    # 
    # 1. index: The position of the character
    # 2. character: The character at that position
    for index, character in enumerate(guess_word):
        
        # Compare the current character in the guess word
        # to the goal word character at the same position
        if character == goal_word[index]:
            # Current character in the guess word
            # matches its counterpart in the goal word
            print("green")
        elif character in goal_word:
            # Current character in the guess word
            # DOESN’T match its counterpart in the goal word,
            # but DOES appear in the goal word
            print("yellow")
        else:
            # Current character DOESN’T appear in the goal word
            print("gray")

…and here’s the JavaScript implementation:

function wordle(guessWord, goalWord) {
    
    // Go through the guess word one character at a time
    for (let index in guessWord) {
        // Compare the current character in the guess word
        // to the goal word character at the same position
        if (guessWord[index] == goalWord[index]) {
            // Current character in the guess word
            // matches its counterpart in the goal word
            console.log('green')
        } else if (goalWord.includes(guessWord[index])) {
            // Current character in the guess word
            // DOESN’T match its counterpart in the goal word,
            // but DOES appear in the goal word
            console.log('yellow')
        } else {
            // Current character DOESN’T appear in the goal word
            console.log('gray')
        }
    }
}        

I call the solution “close enough” because yellow is a special case in Wordle. If the guess word is ATOLL and the goal word is ALOFT, the first L in ATOLL should be yellow and the second should be gray because there’s only one L in ALOFT.

We didn’t settle on the “close enough” algorithm — it was just enough for that night’s session. In the next session, we’ll refine the algorithm so that it matches Wordle’s!

Want to become a better programmer? Join us at the next Think Like a Coder meetup!

Categories
Humor Programming

Is your JavaScript code giving away your age?

Those are literally from the previous millennium!

I don’t use var to declare variables in JS, but there are still situations when a good ol’ fashioned C-style for loop is the appropriate construct.

Categories
Programming

Friday 5: Useful things for coders (March 26, 2021 edition)

Every Friday, I publish the Friday 5, a list of 5 links to useful things for coders.

In this week’s Friday 5: a site that catalogs VS Code’s surprising capabilities, a look at the darker corners of Go, background processing in Android, a full-text search in 150 lines of Python, and generating brighter and darker versions of color in JS.

VSCodeCanDoThat.com

Visual Studio Code is a far more capable editor than you might suspect, and the VS Code Can Do That?! can help you discover tips, tricks, and techniques to help you get the most out of this editor.

Each tip/trick/technique comes with a video showing the tip/trick/technique in action and a link to a more detailed description of the tip/trick/technique.

Check it out: VSCodeCanDoThat.com

Darker Corners of Go

The Go (golang) gopher holding a flashlight

Rytis Bieliunas writes:

While simplicity is at the core of Go philosophy you’ll find in further text it nevertheless enables numerous creative ways of shooting yourself in a foot.

Since now I have used Go for production applications for several years and on the account of the many holes in my feet I thought I’d put together a text for the fellow noob students of Go.

My goal is to collect in one place various things in Go that might be surprising to new developers and perhaps shed some light on the more unusual features of Go. I hope that would save the reader lots of Googling and debugging time and possibly prevent some expensive bugs.

Check it out: Darker Corners of Go

Background Processing in Android

Screenshot of Android app doing background processing

Here’s an article from the Auth0 Developer Blog, where I’m one of the writers/editors:

Android apps use the main thread to handle UI updates and operations (like user input). Running long-running operations on the main thread can lead to app freezes, unresponsiveness and thus, poor user experience. To mitigate this, long-running operations should be run in the background. Android has several options for running tasks in the background and in this article, we’ll look at the recommended options for running different types of tasks.

This article uses Java and covers threading, WorkManager, and AlarmManager.

Check it out: Background Processing in Android

Building a full-text search engine in 150 lines of Python code

Flow diagram showing text tokenization

If you’ve wondered how full-text search engines work and thought about building your own, this basic implementation in Python is worth trying out. In this article, you’ll build an engine that searches Wikipedia’s article abstracts and ranks them for relevance, and it’ll do so in milliseconds!

The article covers these major topics:

  • Collecting and formatting the data
  • Indexing the collected data (which includes stemming the words in the data to their basic forms)
  • Searching
  • Ranking results by relevance

Check it out: Building a full-text search engine in 150 lines of Python code

Generate Brighter And Darker Versions Of Color With JavaScript

Chart showing lighter and darker versions of the color redTinyColor is a fantastic JavaScript library that can help you out with a whole bunch of tasks when you’re working with colors. This article takes a quick look at this more-useful-than-you-might-think library.

Check it out: Generate Brighter And Darker Versions Of Color With JavaScript

Are there useful things for coders that should appear in the next edition of Friday 5? Let me know at joey@joeydevilla.com!

Categories
Humor Programming

Developer meme of the day

Photo: Chef (labeled “developers”) pouring olive oil from a comically oversized bottle (labeled “JavaScript”) onto a salad (labeled “website”).
Tap to view at full size.

Not pictured: A oil drum-sized barrel of balsamic vinegar labeled “React”, “Vue”, or “Angular”, and a forgotten can of anchovies labeled “jQuery”.

Thanks to Cameron Barrett for the find!

Categories
Programming Reading Material What I’m Up To

JavaScript books that you can read online for FREE

My actual setup at my old office (February 3, 2020), where I coded in JavaScript all day.

If…

  1. You’ve decided to learn JavaScript (or just need a refresher), and
  2. you’re short on cash due to the current economic situation

…you’re in luck! There are a couple of good books on JavaScript whose contents are available to read online, free of charge!

The first of these books is Eloquent JavaScript, Third Edition, written by Marijn Haverbeke and published by No Starch Press. It’s not just an introduction to JavaScript, but an introduction to programming in general. It’s beginner-friendly, which is one of the reasons why it’s the main book for the first part of the JavaScript/React course that I’m teaching.

You can Eloquent JavaScript, Third Edition online here.

The second book is JavaScript for Impatient Programmers, ECMAScript 2020 edition, written by Dr. Alex Rauschmeyer. Its coverage of JavaScript is more complete, but it’s a little less beginner-friendly, which is why it’s the backup book for my course. I’m going to incorporate some of its content into the course, and point students to the online edition if they’d like some additional reading material.

You can read JavaScript for Impatient Programmers, ECMAScript 2020 edition online here.

Categories
Career Programming

Programmer interview challenge 2, part 5: An elegant “watcher”-based FizzBuzz implementation in JavaScript

Silhouette of a little black dress on a dress form
Ask someone who follows fashion what they think of when the word “elegant” comes up, and they’ll often come up with the Little Black Dress.

In the previous article in this series, I put out a call for alternate implementations of the “watcher”-based FizzBuzz solution. Frank Quednau answered the call with this elegant bit of JavaScript:

const wordWatcher = (interval, word) => {
  let count = 0;
  return () => {
    count++;
    if (count === interval) {
      count = 0;
      return word;
    }
    return "";
  }
}

const fizzWatcher = wordWatcher(3, "Fizz");
const buzzWatcher = wordWatcher(5, "Buzz");

for (number of Array(100).keys()) {
  const potentialFizzBuzz = `${fizzWatcher()}${buzzWatcher()}`;
  console.log(potentialFizzBuzz ? potentialFizzBuzz : number + 1);
};

Let’s take a closer look at the code for the watcher, which is assigned a word and keeps track of when to say it:

const wordWatcher = (interval, word) => {
  let count = 0;
  return () => {
    count++;
    if (count === interval) {
      count = 0;
      return word;
    }
    return "";
  }
}
  • wordWatcher has two parameters:
    • interval: The x in “Every xth number”
    • word: The word to be output
  • It uses those parameters to customize the function that it returns: a function that when called, does two things:
    • It increments its internal counter count, and
    • returns either word (if it’s time to say the word) or an empty string.

If you find yourself writing a lot of similar code with only minor differences — or worse, cutting and pasting code, followed by typing in those minor differences — you may be looking at an opportunity to use a function like this.

If you prefer to have your functions marked with the keyword function, you can change out the arrow notation and the code will still work:

function wordWatcher(interval, word) {
  let count = 0;
  return function() {
    count++;
    if (count === interval) {
      count = 0;
      return word;
    }
    return "";
  }
}

With wordWatcher defined, creating watchers for Fizz and Buzz is easy:

const fizzWatcher = wordWatcher(3, "Fizz");
const buzzWatcher = wordWatcher(5, "Buzz");

And here’s the loop that provides the output:

for (number of Array(100).keys()) {
  const potentialFizzBuzz = `${fizzWatcher()}${buzzWatcher()}`;
  console.log(potentialFizzBuzz ? potentialFizzBuzz : number + 1);
};
  • If it’s time to say FizzBuzz, or FizzBuzz, potentialFizzBuzz will contain that string. The calls to fizzWatcher() and buzzWatcher() will also increment their internal counters.
  • If potentialFizzBuzz contains anything, its contents will be printed to the console; otherwise, the current number — which has 1 added to it because array indexes start at 0 and the FizzBuzz game starts at 1 — is printed instead.

You should check out the rest of Frank’s Gist, Fizzbuzzes in many colours, which looks at FizzBuzz solutions written in several languages.

What does it mean for code to be “elegant”, anyway?

In ordinary everyday use, elegant means “pleasingly graceful and stylish in appearance or manner.” The term has been adapted by people in problem-solving fields — science, mathematics, and yes, programming — to mean “pleasingly ingenious and simple”.

And that’s what elegant code is: pleasingly ingenious and simple. This FizzBuzz implementation is elegant because it solves the problem in just over a dozen lines, is simple and concise, and even provides some new insight into programming (the use of custom-generated functions to avoid repetition).

Here’s a good list of qualities of elegant code, courtesy of Christopher Diggins article, What is the Definition of Elegant Code?:

  • It is succinct
  • It is easy to understand
  • Each function does one well-defined task
  • It conveys the programmer’s intent
  • It reflects the problem domain
  • It is easy to modify and reuse
  • If it fails, it is easy to identify that it is has failed, where it has failed, and why it has failed.
  • Its behavior (in good and bad conditions) is easy to predict

Check out the following articles — sooner or later, you’ll be interviewed by a programmer who’ll want to know if you’ve given some thought to some of programming’s more philosophical questions, and “What does it mean for code to be elegant?” is one of them:

What’s next

FizzBuzzBazz! (or: Making FizzBuzz harder).

Previously, in the “Programmer interview challenge” series

 

Categories
Career Programming

Programmer interview challenge 1, revisited: Revising “Anagram” in Python and implementing it in JavaScript

In the previous article, I wrote about a challenge that’s often given to programmers at a tech interview: Write a program that determines if two words are anagrams. I posted a solution in Python; check it out here. In this article, we’ll refactor the Python code and write a JavaScript implementation.

Refactoring the Python version

Looking at the code for anagram(), it’s quite clear that it isn’t DRY (Don’t Repeat Yourself), but manifestly the opposite: WET (Write Everything Twice)!

Under the time constraints of a technical interview, you might not always have the time or cognitive bandwidth to keep your code DRY, but if you should try to do so if possible. You may find that it helps convey your algorithmic thinking more effectively to the interviewer, and that’s what you want. After all, your goal throughout the process is to prove that you can actually program.

The repeated code is the part that takes a string, sorts its characters into alphabetical order, and removes the leading space if it exists. Let’s turn that code into its own method:

def sortLetters(word):
  # Returns the given word with its letters sorted
  # into alphabetical order and with any
  # leading space removed.
  word_lowercase = word.lower()
  return ''.join(sorted(word_lowercase)).lstrip()

With this method defined, we can use it in anagram(). In fact, we can nest it within anagram(). Here’s the revision:

def anagram(first_word, second_word):
  # Returns True if the given words are made of the exact same characters,
  # ignoring capitalization and spaces.

  def sortLetters(word):
    # Returns the given word with its letters sorted
    # into alphabetical order and with any
    # leading space removed.
    word_lowercase = word.lower()
    return ''.join(sorted(word_lowercase)).lstrip()

  return sortLetters(first_word) == sortLetters(second_word)

Creating the sortLetters() method doesn’t just DRY up the code, but helps the method better convey what it does. Now, what anagram() does is very clearly conveyed by its return statement: it tells you if the first word with its letters sorted is the same as the second word with its letters sorted.

I confirmed that this refactored code works by running the tests, which show just how useful having tests is.

Implementing anagram() in JavaScript

Here’s anagram() in JavaScript:

function anagram(firstWord, secondWord) {
  
  function sortLetters(word) {
    return word
      .toLowerCase()
      .split('')
      .sort()
      .join('')
      .trim()
  }

  return sortLetters(firstWord) === sortLetters(secondWord)
}

Note that the JavaScript version of sortLetters() is structured slightly differently from the Python version. That’s because JavaScript’s sort() is an array method rather than a general function like Python’s sorted().

In the JavaScript version of sortLetters(), I use method chaining to spell out what happens to the given word step by step:

  1. Convert the word to lower case
  2. Convert that into an array of characters
  3. Sort that array
  4. Convert that array into a string
  5. Remove any trailing or leading whitespace

I could’ve written sortLetters() this way…

function sortLetters(word) {
  return word.toLowerCase().split('').sort().join('').trim()
}

…but I find that “put each method in the chain on its own line” approach more clearly conveys what I’m trying to do:

function sortLetters(word) {
  return word
    .toLowerCase()
    .split('')
    .sort()
    .join('')
    .trim()
}

Next: The Swift version!

Previously, in the “Programmer interview challenge” series