I recently tried to connect to my Sensi Touch Smart thermostat to WiFi, and I ran into a lot of issues getting it to work. Sensi’s supportpages were helpful for general guidance, but they could benefit from more detail and explanation. Hopefully this post will help save somebody else some headaches.
Below are some steps to follow after downloading and signing in to the Sensi mobile app. The app has a straightfoward flow in the user interface; the WiFi connectivity is the harder part. Your specifics may vary, but the general principles should be the same.
Check Your Phone’s Wifi and Network Settings
Connecting the Sensi thermostat to WiFi first requires connecting your phone to Sensi’s local WiFi. This connection doesn’t have internet access, but is required for setup. Phones often have settings that will auto-connect to different WiFi networks under various conditions. These are normally nice features, but they kind of get in our way here.
Android phones will often warn you about the internet quality when you try to connect to Sensi’s WiFi for the first time. Make sure you allow the connection and check the box to prevent it from asking again.
Here are some other settings to try in order to force your phone to connect to Sensi’s local WiFi:
Turn off mobile data.
Turn off the auto-connect feature of your home WiFi connection.
If you’re using a VPN, disable it.
After toggling these settings, try connecting to the WiFi. If you’re still having problems, you may have another issue that needs resolving.
Force Sensi Touch Smart Thermostat to Connect to WiFi on 2.4 GHz
You may need to set up a dedicated 2.4 GHz WiFi connection for your thermostat to connect to. Sensi thermostats use an 802.11n 2.4 GHz Wi-Fi radio. A lot of modern devices run on the 5 GHz band, and many routers are dual band. For the Sensi thermostat, the trouble connecing comes when both frequency bands have the same SSID (name).
There are a couple solutions to this problem.
You can set up a Guest SSID under a different name that runs on 2.4 GHz.
You can also configure your network to have different SSID names for the 2 different bands.
Personally, I went with the Guest SSID option. It was easy and avoided having to reconnect other devices.
Your router should have configuration information on it, including an IP address you can navigate to in your web browser. This web page will allow you to configure your network settings. For AT&T, it was as simple as Home Network -> Wi-Fi -> Guest SSID Enable -> Pick a Guest Network Name/Password.
This new guest network should show up under available WiFi networks, and you should select it when choosing which network the Sensi Touch Smart thermostat should connect to.
If you’ve never experienced the relatively recent phenomenon of escape rooms, you should really change that. They’re a lot of fun. Recently my family attempted to escape from a difficult one unsuccessfully, and it got me thinking about all the things we should have done differently. Since it has been ages since I’ve posted anything, I figured I’d share some of those thoughts. So here it is, how to escape from an escape room.
Escape Room Tips and Tricks
Think simple. Clues won’t usually require specialized knowledge to solve. If you received sheets of music, look at the names and the words, not the notes on the page.
If tasks are partitionable, assign them to different people. You want to avoid having too many cooks in the kitchen. For example, if pictures of people have date ranges, pre calculate ages, who is the oldest, etc, while others in your group are solving puzzles. You might need that information later.
Think before speaking, to avoid distracting those are trying to solve puzzles. However, talking through what you’re thinking can help when people are stuck.
Turn off/on lights. Some rooms use black lights.
If a switch appears not to work, have somebody in another room check if something is happening.
Look through peepholes in doors or similar openings in pictures, etc.
Keep in mind what types of combinations you’re looking for based on the locks. Are you looking for numbers or letters? How many characters are you looking for?
Look on the underside of tables and other objects in the escape room, not just in obvious places that draw your eye.
Search for hidden doors and rooms. Unlocked a wardrobe? Try walking through it, Narnia style.
Recognize when you’re spinning your wheels. If you have an allocated number of hints to use it’s better to burn one early if you’re just going to be wasting time.
If you are in a room where the host can always communicate with you, be ready to think outside the box. Possibilities open up when you aren’t constrained by having to put in a physical combination to “unlock” the next part of the escape room.
Let others work on the puzzles you aren’t good at. Old as dirt? Let young people with good eyes and nimble fingers read clues aloud and put in combinations on locks. Suck at math? Leave the marker and whiteboard on the table.
There you have it, some tips and tricks to help you escape from an escape room.
Subscribe to my blog or follow me on Twitter if you’re interested in computer programming content or seeing more random content like this.
I visit the Hacker News website fairly regularly. It has a lot of great information and interesting discussions. One section I particularly enjoy is called “Ask HN”. People ask for advice on all sorts of topics. There are usually nuggets of wisdom and lively debate that follows in the comments.
I often find myself reading through these comments and saving off interesting looking links to other websites. There is a lot of collective wisdom and experience to be found there.
I felt like it would fit the spirit of Hacker News to automate that process and create a spin-off website that collects and displays some of the day’s hacker wisdom.
You can see the result by following this link, which also has a link to the source code on Github.
The rest of this post will be dedicated to describing how I built it.
Setting up the Project
I used IntelliJ for my IDE, and that tool makes it really easy to set up a Maven/Spring Boot project.
Spring Boot and its associated addons made it really easy to add Controllers to handle web requests, Services to handle the logic, and Thymeleaf templates to handle the front end.
Each controller method maps to a Thymeleaf template. The about page is static, but the home page is populated with dynamic data from the “Ask HN” section of Hacker News.
Retrieving the Links
I used to two API endpoints to retrieve the links:
The first endpoint gets me a list of ids, in the form of integers, of the top “Ask HN” posts. The second endpoint will retrieve any item, whether a post or a comment, by id. With the help of a recursive function, these two endpoints allowed me to drill down into the comments of these “Ask HN” posts.
Once I had the comments I had to look for the links contained in their text. I know that using a regex to parse HTML is generally a bad idea, but I was able to make it work. I didn’t feel compelled to pull in JSoup as a dependency once I had it working consistently.
After retrieving the links I removed duplicates and sorted them for a better user experience. I created a custom, case insensitive link sorter that ignores the http(s) prefixes.
Improving Responsiveness
Unfortunately, while my solution up until this point was accurate, it was not very fast. It takes a lot of API calls to retrieve all the necessary data, and those trips add up. The time can also vary depending on how popular the question is. Without any optimizations, this was taking an unacceptably long time.
My solution to this problem was to implement a caching strategy using Spring’s caching capabilities. The application stores the data in a cache with a name of “answeredQuestions” after retrieving it for the first time.
Meanwhile, in the background, a scheduled job will reperform the data parsing and update the cache every 10 minutes. I used Spring to implement the scheduling as well.
After the first request succeeds, subsequent requests bypass all of the calculations and can simply grab the stored result from the cache.
Playing those games is one of my earliest and fondest memories on the internet. I remember making the trip to my elementary school’s computer lab where we were allowed to visit coolmath4kids.com (which looks a lot different decades later) because the games were supposed to be educational.
Despite the best efforts of our teacher to police it, we all snuck over to a section of the website known as “Spike’s Game Zone”. This was where the mindlessly fun games were.
As I grew up my tastes became more sophisticated. One flash game that I found very addicting as a kid was simply called “Dice Wars”. It’s like the board game “Risk” in a lot of ways, but with a little more luck involved. If you want to play the original, you can check it out here.
Minimum Viable Dice Wars
I decided it would be a fun project to try to build my own version of Dice Wars. I’m calling it, “Minimum Viable Dice Wars”, as it’s a bit different and not nearly as polished as the original. However, it is playable and has most of the same major features.
One thing I always get self-conscious about when I share more ambitious side projects with you all is the code quality. I make these games in bits of my spare time. As somebody who builds software professionally, I’m never quite satisfied with the end result.
Most of the algorithms in this project are brute force approaches, and there are plenty of performance optimizations that I could make. However, if I held off on sharing these projects until they were perfect I’m not sure I’d ever publish anything.
Instead of walking through all of the code and explaining it line by line, as I have done in some of my previous tutorials, I’ll be focusing on the approaches I took while implementing the more interesting sections.
I took a similar approach when discussing the crossword puzzle generator. It’s another project with a bit higher level of complexity, and that approach seemed to work well for demonstrating concepts without getting bogged down in the details.
Of course, feel free to ask questions about any particulars you find interesting or confusing.
Game Board Generation
I’m pretty sure the original version of Dice Wars uses some kind of tree or graph data structure for representing the game board. It really intrigued me how the original developers built it and integrated it with the graphics.
Going with the “minimum viable” theme, however, I decided to go with a 2D array. It gives the game a bit of a unique feel too, in my opinion.
The basic approach I took for generating random boards looks like this:
Generate an empty square board of fixed size using a 2D array.
Pick a random, but reasonable, number of tiles to make empty. When choosing the random placement of the tiles, don’t let these empty tiles be on the “inner ring” of the board. This will help us avoid creating hanging tiles. A hanging tile is one that doesn’t connect to any other tile and thus can never be captured.
Randomly assign the same amount of dice to each team on the available tiles, and make sure they are distributed in varying amounts.
Clean up any hanging tiles. The code I wrote for this doesn’t cover all cases, but I think it is sufficient given the additional precautions taken in step 2 above.
Find Connected Tiles
One key element of Dice Wars is that you get bonus dice based on your largest group of connected tiles. This proved to be tricky, and I’ll admit I used Stack Overflow for a bit of initial direction. Once I understood the basic idea I was able to modify it to fit my use case.
The general idea is to loop through all the tiles on the board and use recursion to check each tile’s connected tiles to see if they are owned by the same team….and then do the same thing for each of those connected tiles…and so on.
Once all the branching tiles have been checked and the base case has been reached the function returns the connected tile count along with an array of the connected tiles.
I started by creating an array of the neighboring tiles. I represented each tile as an object containing coordinates, a name designating the directional relationship to the original tile, and whether it was a valid direction given its position on the game board.
The result of this function helps to simplify the recursive code. It allowed me to loop through the array and call the same function repeatedly instead of checking multiple if statements like shown in the Stack Overflow example.
I added the tile to an array and incremented the total count whenever it was valid, belonged to the same team, and hadn’t already been checked.
Artificial Intelligence
It took a bit of tweaking, but it turns out a few simple rules are all it takes to create a serviceable AI for a Minimum Viable Dice Wars. There are two main things the AI does. The AI will attack from a tile if:
It is adjacent to a weaker tile owned by an opposing team.
It has the maximum number of dice and is adjacent to a tile owned by an opposing team that also has the maximum number of dice.
There are many ideas for improvement I haven’t implemented yet, including ranking the attack options, focusing attacks on the team in the lead, and attacking again from a conquered tile after a successful attack.
It seemed pretty fun to play against though, so I haven’t bothered with it yet.
Conclusion
I had a lot of fun making this minimum viable version of Dice Wars. I hope you enjoyed following along. Subscribe to my blog or follow me on Twitter if you’re interested in seeing more projects like these.
Welcome to my latest tutorial, where you’ll learn how to build a magic eight ball with JavaScript.
I usually write tutorials for an audience of people who know at least a little bit of front-end programming. I’ve put more focus on the concepts and thought processes used in building the abstractions than on the technical details. One of my recent tutorials, a crossword puzzle generator, is a good example of what I’m talking about.
This post will be different. I’m going to show you how to build a magic eight ball with JavaScript, and the tutorial is designed for complete beginners.
And you can view the source code here. You can compare your code to mine if you run into troubles along the way.
My tutorials are fun because you get a working game at the end. I think there is a lot to be said for that. Most people don’t get into programming because they enjoy sorting lists or learning about data structures. They want to build something cool.
That being said, my tutorials usually require you to apply yourself and do more of your own research if you want to maximize the benefits to you. If you’re just blindly copying and pasting you won’t learn much.
True growth as a developer comes when you can combine structured learning of the fundamentals with building cool stuff.
The goal of this specific tutorial is to provide that kind of experience, with a little more focus on learning the fundamentals.
Technologies of the Web
We’ll be building this magic eight ball using front-end web technologies. Understanding these technologies is key to building a strong foundation as a web developer.
There are three fundamental technologies that every developer must know in order to write code that will run in a web browser: HTML, CSS, and JavaScript.
HTML
HTML stands for hypertext markup language. It is a domain specific programming language that allows you to display structured content in a web browser.
Notice how this page you’re reading has headings in larger font and breaks between paragraphs? That effect is due to HTML tags.
What are tags?
Tags are elements on the page that describe how content should be displayed. There are different tags for displaying headings, paragraphs, buttons, line breaks, images, and much more. If you want to be a web developer, HTML is the first thing you should learn. Fortunately, it’s pretty easy to pick up.
CSS
CSS stands for cascading style sheets. It is a programming language used for applying colors, fonts, positioning, borders, and much more to HTML elements. Basically, it makes the page look pretty.
It’s called cascading because of the way it determines which style to apply if more than one rule matches a particular element.
CSS can be included in the HTML directly, or pulled in from a separate file. It used to be considered poor form to have inline CSS, but that standard has changed a bit with some of the new front-end frameworks. For this tutorial, I’ll be including the CSS via a separate file.
JavaScript
Out of the three languages, JavaScript is probably the most challenging to learn (although advanced CSS can get pretty crazy). It’s also the most rewarding, as many of the same concepts will apply to other programming languages, like Java, Python, or C++.
JavaScript brings your page to life. It allows you to introduce dynamic behavior to the page. You can add functionality that is dependent upon the actions of the user. It’s where the bulk of the difficulty, and fun, of programming lies.
Like CSS, you can include JavaScript directly in the HTML. I’ll be including it via a separate file.
We’ll be displaying the answers from our magic eight ball with JavaScript.
Where To Write The Code
To start developing for the web, all you really need is a text editor program. I like Sublime, but there are many good ones to choose from. You can even use plain old Notepad, but I recommend downloading something better. Here is a good list to pick from:
Sublime
Visual Studio Code
Notepad++
Atom
Make Your Life Easier With a Debugger
In my opinion, it’s also worth familiarizing yourself with your browser’s developer tools. They are extremely helpful for experimenting, debugging issues, and seeing what’s going on in your code behind the scenes. For this tutorial I’ll be using Google Chrome.
In Chrome, you can bring up the developer tools by using the keyboard shortcut: Ctrl + Shift + I, or by right clicking on the page and selecting “Inspect”. Check out this post to familiarize yourself with the basics of how to use these tools.
Alternatively, you can wait and learn them when you need them.
Creating the HTML File
Ok, let’s get started making the magic eight ball.
Once you have downloaded a text editor you have all you need to begin. Pick any folder/directory on your computer as the location of your website. It can be a simple as creating a folder called “magic-eight-ball” on your Desktop. This is the location where you will be saving your HTML, CSS, and JavaScript files.
Next, open up a brand new file in your text editor of choice. This is where we are going to write the HTML code.
This is the basic structure of an HTML document. The words in angle brackets are called tags.
There are opening and closing tags. The tags that have a forward slash before the name are the closing tags. Although most HTML elements require both, there are many HTML elements that do not require a closing tag. We’ll see some examples of this in a moment.
The content you will be adding goes between the opening and closing tags. These tags are what create visible elements on the page.
The first element you see is the doctype. This is not an HTML tag, but information the browser needs to know what kind of document to display. In our case, the type of document is an HTML document. There are other doctypes, but that discussion is beyond the scope of this tutorial.
We have three tags so far: html, head, and body. The html tag signifies the beginning of the HTML document. Everything on the page goes inside it. The head tag contains meta information about the page and can also be used as a place to import other files. The body tag is where the bulk of our content will go.
Go ahead and save this file as index.html in the folder you previously created.
Now add some more code so your HTML looks like this:
Let’s look at what we added. You should notice that the head and body tags have even more tags inside of them now.
Head Tag
We have added a title tag and two link tags. The title tag will be displayed in the tab of your browser.
The first link tag pulls in the CSS class which we have yet to create. We’ll do that in a moment.
The second link tag sets the favicon image. This is the little icon that shows up in the browser tab. We’re pulling the image from the web server that runs my blog.
Body Tag
We have added a main tag inside the body. This element contains the main content of the page. In our case, this is almost everything. On other websites, however, you might find items like common footers and navigation elements outside of the main tag.
Inside our main tag we have added two h tags. These are heading tags that display larger text meant to serve as headings for sections of content.
The first heading tag contains text representing the title of our page: Magic Eight Ball. It also contains a class property labeled “heading”. This is a CSS class. Later we will add style to it by adding code to our CSS file.
Adding Hyperlinks
The second heading tag, which is also assigned the “heading” class, contains hyperlinks to my blog and Github page.
You might know hyperlinks by their more common nickname: links. These hyperlinks are created by using “a”, or “anchor” tags. The href property specifies which url the hyperlink will direct the browser to. The text between the anchor tags specifies what the link name will be.
You should really click on that Subscribe link and submit the form. I’ve made it easy for you by adding my own link to it right here. 😉
At this point you should save your changes. Then, navigate to this file and open it in a browser. In the address bar you should be able to see the path to your file. On the page itself you should see the title and the links below it.
Finishing Up the HTML
Now it’s time to add the rest of the HTML content. See the new additions below:
In this step we’ve added the bulk of the HTML needed to make our magic eight ball. We’ve added two div tags. People use div tags a lot. You can think of them as generic placeholders for content.
Adding the “Shake It” Button
The first div is given the id of “answerButton”. We’ll use this id for adding styling via CSS. Inside the div tag is a button child tag.
Child tags are tags inside of other tags. The outer tag is referred to as the parent tag. (Image description?)
This button is assigned the class “button”, the type “button”, and a JavaScript function to execute when somebody clicks it. We’ll write this function later when we get to the JavaScript file. The text on the button will say “Shake It”. When you click this button, you’ll get an answer from the magic eight ball.
The second div is given the id of “magicEightBall”. We’ll use this id for adding styling via CSS, but also for adding functionality in the JavaScript code.
Adding the Magic Eight Ball
There are two child tags in this div. The first is another div with the id of “circle”. The second is an img tag with a src attribute pointing to an image called “magic-eight-ball.png”. You’ll need to download this image from my server, give it the name “magic-eight-ball.png”, and save it in your working folder/directory along with your other files.
There are also br tags scattered throughout to provide spacing between different page elements. Go ahead and add those as well.
Finally, there is a script tag right outside the main closing tag. The src attribute points to magic-eight-ball.js, the JavaScript file we will be adding later.
If you save and open the HTML file now it will have all the content, but it will look pretty ugly:
We’re going to fix that by adding the CSS file, magic-eight-ball.css.
Creating the CSS File
Open up a brand new file in your text editor and save it in the same location as your index.html file under the filename, “magic-eight-ball.css”.
It’s important that the name matches the one you specified in the HTML file, otherwise the CSS file won’t be found. Add the following blocks of code one at a time, and save as you go. Observe how the page changes as you go.
Setting the Background Color
body {
background: cornflowerblue;
}
This block of code does one thing and one thing only. It sets the background color of the body HTML element to a nice blue color. If you save the file and refresh your browser you’ll notice the color change.
Centering the Page Contents
main {
max-width: 610px;
margin: auto;
}
After refreshing the page you should see everything centered on the page much more nicely. We have set the max width of the main element to 610px (px stands for pixels), and we have set the margin to auto, horizontally centering all of the content within it.
This block of code is applying styles to four different HTML elements: all h3 tags, all h5 tags, the HTML element with the id of “answerButton”, and the HTML element with the id of “magicEightBall”.
By adding this code block we will apply three different styles to these elements. We’ll center the text within them, set their text color to khaki, and set the margin (the space around the element) to 5px.
There is a lot going on in this code block. We are applying many different styles to the HTML element with the id of circle, which represents the area where the answer will appear.
We are setting the font size to 14pt. This seemed reasonable after I did a little bit of testing. We are also setting the background to white and the text color to black so that the answer area will have good contrast and look good on top of the magic eight ball image.
We are using absolute positioning. This will cause the element to be positioned relative to the nearest position ancestor, which in our case is the HTML element with the id of “magicEightBall”. We are also adding left and top margins of 70px to help us begin centering the answer area in the middle of the magic eight ball.
We are setting the height and width of element to 150px, creating a square. Then we set the border radius to 50% which rounds the corners into a square.
Finally, we set the display to none, hiding it from view until the person shakes the magic eight ball.
Now the magic eight ball looks a lot better:
Creating the JavaScript File
Now it’s time for the fun part. We’re going to make our magic eight ball come to life with JavaScript.
Open up a brand new file in your text editor and save it in the same location as your index.html file under the filename, “magic-eight-ball.js”. It’s important that the name matches the one you specified in the HTML file, otherwise the JavaScript file won’t be found.
Creating the Answers Array
The first thing we’re going to do is create a list of possible answers the magic eight ball can respond with. We’ll refer to this list as an array. The term array is very common among different programming languages. Simply put, it is a structure for storing a sequential list of data in memory. In our case, the data will be the answers that the magic eight ball will give to us. Let’s define the array in our code:
let answers = [
'Seems unlikely.',
'Not a chance.',
'In your dreams.',
'Get real, kid.',
'Absolutely.',
'Maybe.',
'It is certain.',
'Ask me later.',
'Chances seem good.',
'I don\'t know, I\'m just a stupid piece of plastic.',
'Ask again later.',
'Signs point to yes.',
'No.',
'Yes.',
'Nope.',
'Don\'t count on it.',
'Is the Pope Catholic?',
'Does a one legged duck swim in a circle?'
]
We’ve used the let keyword to define a variable named answers. A variable is a name that refers to a piece of data.
We have set this answers variable (via the = sign) to hold an array of strings. For this tutorial, you can think of a string as a sequence of characters. We’ll be using strings to represent our answers.
A comma is used to separate each element of the array. By adding the code above we have defined a variable that holds an array containing 18 answers, each represented as a string.
Creating the displayAnswer Function
Now let’s add the JavaScript function to display the answers when the player clicks the “Shake It” button.
let displayAnswer = function()
{
let index = Math.floor(Math.random() * answers.length);
let answer = answers[index];
let element = document.getElementById( 'circle' );
element.style.display = 'inline-block';
element.innerHTML = '<br><br>' + answer;
}
We’ve defined another variable, but this time we have pointed it to a function instead of an array. You can think of a function as a container for code that can be reused. You can run the code inside by “calling” that function.
If you search through the index.html file we created and look for displayAnswer() you’ll see where this function is called from. Whenever we click the “Shake It” button, this function will be called.
Functions are very useful to us as programmers. We can use them for organizational purposes and to prevent us from writing the same code over and over again.
Inside our displayAnswer function is code that will show a random answer on the magic eight ball. Let’s break down each line.
Getting a Random Index
let index = Math.floor(Math.random() * answers.length);
The first thing we do is get a random index. This random index will correspond to one of the elements in our answers array. Each element in the array is assigned an index, starting with 0. So the array above looks like this:
We generate this random index by using a few functions provided by JavaScript’s built in Math object. We multiply the length of the answers array by a random number between 0 (inclusive) and 1 (exclusive). Then, we round it down to the nearest integer.
Picking a Random Answer
let answer = answers[index];
Once we have our random index we need to retrieve the corresponding answer from the array. We do this by declaring a new variable and setting it to a value in the array corresponding to that index.
Finding the Circle
let element = document.getElementById( 'circle' );
Once we have our answer we need to display it on the page inside the magic eight ball. The first step is finding the HTML element. We use the above line of code to grab the element with the id of “circle”. In this case “document” refers to our web page. We save off a reference to it in a variable named “element”.
Displaying the Circle
element.style.display = 'inline-block';
Now that we have the element we need to make it visible. Remember, in our CSS file we previously hid this element from view. We will change its display from “none” to “inline-block”.
Showing the Answer
element.innerHTML = '<br><br>' + answer;
Finally, we need to populate the element with the answer. We’ll create a string of two br tags, to help center the answer in the middle of the circle, and then append the answer to it. The plus symbol can be used for doing math, but in the case of strings it will concatenate them together.
Now save your file and check out the game you’ve created! You should get a random answer every time you click the “Shake It” button.
Congrats, you have created a magic eight ball with JavaScript!
I hope you learned something from this tutorial, especially if you are brand new to programming. We have barely begun scratching the surface on what we can accomplish with these programming languages. The whole web is built using these technologies, and there are many more elements we can create, styles we can apply, functions we can write. There is boundless room for creativity.
If you’d like to keep learning more, check out some of my other game tutorials.
It’s the beginning of a new year, so I figure it would be a good time for a reflective post. I could write about the pandemic or the political tension that seems to be ubiquitous these days, but I’d rather talk about something more fun and uplifting.
I also needed a catchy title using alliteration that I can reuse next year. Maybe “Mitchum’s Morbid Meditations” would be pretty accurate for 2020, but it didn’t seem like the sort of thing any of you would want to read.
In this post I just want to share some content I read, watched, or listened to last year that brought value to my life in some way. Maybe one of these will bring some to yours too.
The Queen’s Gambit
My wife and I really enjoyed watching this Netflix show together.
We both like playing chess. I win more often when we play long games, and she wins more often when we play shorter, blitz-style games. She’s very good at going with her gut and making solid moves, and I’m very bad about clumsily knocking over pieces when trying to move quickly.
We both enjoyed the show a lot and it got us playing more chess together, so it was a double win. It also inspired me to start educating myself more about the game.
The Simple Path To Wealth
Until recently, I was pretty ignorant about the stock market. This stock series by JL Collins helped changed that.
It taught me about how the market works and the advantages of investing in broad-based index funds over a long period of time. I can’t recommend it enough if you want to plan for your retirement and are confused about where to start. His sound advice cuts through all the noise and will deliver on the promise of the title of his blog if you hold the course.
Indie Hackers Podcast
Sometimes I daydream about creating my own profitable software product that I can share with others. So I really enjoyed listening to this podcast over the past year.
It’s basically a series of interviews with people who have started successful online businesses with very small amounts of funding and personnel. The tools for creating software products have improved tremendously in recent years, and have really broadened the possibilities for entrepreneurship.
Hearing these kinds of success stories inspire me to work on small projects of my own. Even if they don’t lead anywhere, I usually learn something new and enjoy the journey.
Christmas in the Trenches
I heard this John McCutcheon song for the first time this year and was really moved by it, especially once I learned about the history behind it.
It’s based on an event that actually happened on Christmas during World War I. Soldiers from opposing armies actually left the trenches, sang Christmas songs, and celebrated together before going back to war.
The message of the song is one of peace, and how “on each end of the rifle we’re the same”. I think the message really hit home with me this year as the political polarization has continued to rise in the country. Here’s a version of it by a guy I like to hear perform and preach.
The Mandalorian
I’m a big fan of both Star Wars and spaghetti westerns, so I’ve really enjoyed watching The Mandalorian series. I’m also really thankful I can mooch off my family’s Disney+ account.
I was less than thrilled with the new movie trilogy, but I think The Mandalorian has steered the franchise back in the right direction. Season two was a solid story that integrated fan favorite characters very well. I’m excited to see what the future holds for the franchise.
If you log into Facebook very often you’ve probably been bombarded with relentless calls to action. Those kind souls in Silicon Valley seem to really care about democracy (or something else), and have been encouraging voting for weeks on end.
It’s probably good to remind people to register to vote. We all live busy lives and are prone to forget rare but important events (Men, this is your anniversary reminder. You’re welcome).
However, I also find the ongoing persistence of these reminders incredibly irritating. It’s not confined just to Facebook. Today’s culture in the United States treats voting as some kind of moral obligation that all of us must fulfill. I find that idea to be completely ridiculous, and in many cases actively harmful.
Have you been on social media? Have you witnessed the unending stream of nonsense, ignorance, and vitriol? Do you really want all of these people shaping the course of human events?
I think those questions can stand alone as an unassailable argument, but I’ll elaborate so my position on voting is made clear: You shouldn’t let people pressure you into voting, especially if you haven’t done much deep thinking about it.
What is Politics?
Politics is a complex arena, especially at the national level. It involves the intersection of many fields, like economics, history, morality, religion, science, law, and so on. Few, if any of us, could be considered experts in each of these fields.
The best we can do is take what we’ve learned and develop a coherent worldview that gives us a general idea of how the world works. From there we can use our vote to try to shape a better future based on our worldview. Every voter does this, whether they consciously recognize it or not.
What Motives Do Voters Have?
If people voted entirely out of pure self-interest, maybe I could see the appeal of encouraging everyone to vote. People don’t vote that way though.
Have you ever been in a political debate before? Everybody argues that implementing their ideas will be better for society as a whole, not just for themselves. People of all political stripes claim that some ideas may benefit them directly, but overall would be bad for society.
Self-interest certainly plays a role in who people decide to vote for, but it’s far from the only motivating factor.
The Problem of Careless Voting
This leads to a significant problem. By treating the right to vote as a golden calf to worship, we are rewarded with a very large group of people with vastly different levels of wisdom who all feel obligated to weigh in on the complex problems of the world.
Clearly, these people can’t all be correct about their prescriptions for the future. Some might even argue they all are wrong.
You wouldn’t encourage your friend to make an important life decision without first spending some time thinking about it deeply. Why would you encourage voting among people who normally aren’t very interested in thinking about the broad implications of policy decisions?
None of us should want close elections decided by people who voted based on a few click-bait articles they saw the week before the election, or because they were pressured by annoying friends who don’t know what they’re talking about.
If you have to constantly remind somebody to do something, it probably isn’t very important to them.
How We Should Treat Voting
We should treat the right to vote the same way we treat other rights granted to us by the US Constitution. Like any other right, it should be exercised responsibly.
We shouldn’t put such an emphasis on encouraging people to vote. Instead, we should be encouraging people to learn more about how the world works and to use that knowledge to take on new challenges in their own lives.
Read about those different fields and disciplines. Start a business. Learn a new skill. Volunteer in your community. Become friends with people who think differently than you. Travel somewhere new. If you become a more well-rounded person you will be better prepared to make decisions that affect the lives of other people.
Democracy is wonderful, but it is no safeguard against poor decision making.
If this tirade still didn’t convince you, I just have one request to make. When you encourage people to vote, you’re really encouraging them to vote for your preferred candidate, aren’t you? I’m cool with that, but at least be honest about it.
Of course, along with the success came the haters.
I received some criticism on various choices I made. As you should come to expect on the internet, some of it was respectful and some of it was not. However, as all the great ones do, I decided to channel the negative energy to become even better. I’m basically the Michael Jordan of independent, part-time, game tutorial creators.
I considered the feedback I received, ate some humble pie, and realized the haters were correct in many cases. There are definitely improvements that can be made to the original implementation, and I decided to revisit minesweeper to make a few of those changes. Check out the new version, which shouldn’t feel much different than the old one:
The two big improvements I made were removing jQuery as a dependency, and preventing losses on the first click of the game. I also started taking advantage of some of the newer additions to the language, like the “let” keyword for declaring variables.
Take a glance at the git history for this project. I copied the original files into a new directory and removed jQuery from each function until I completely eliminated the dependency from the project. I worked on preventing immediate losses once jQuery was completely gone.
Removing jQuery
The jQuery library was great for its time, but it’s usually an unnecessary abstraction in modern browsers. Today’s browsers are much better at following the same standards, and we now have more native methods for accomplishing just about anything jQuery can do. Most of the changes I made involved replacing jQuery functions with native methods.
However, I still have a soft spot in my heart for jQuery, and I did find one situation while refactoring the code where I really missed having it: event listeners. It’s really easy to add and remove event listeners using jQuery. It keeps track of the references for you, which makes removing them all at once a simple method call that you can chain to other jQuery methods.
In vanilla JavaScript you have to be much more explicit about which event listeners you want to remove. You typically have to pass the callback function to the removeEventListener function, and this can be error prone when dealing with multiple event listeners and different levels of scope.
My first attempt at replacing the event listeners with vanilla JavaScript resulted in adding new event listeners to minesweeper cells every time the player pressed the New Game button. This caused us to process events multiple times on a single cell click. Chaos ensued. You can check out these two commits and see what it took to restore order.
While you’re looking at the changes in that first commit above you’ll also notice the code I added to prevent a loss on the first click. This is a feature in the original game that I did not consider when building the clone. It’s a nice feature to have because it’s pretty frustrating to lose the game on your first click on an empty board.
Here’s the general approach I used to implement this feature.
Keep track of whether it’s the players first click on the board, and reset that variable each game.
If it’s the player’s first click and he’s about to lose, remove the mine and randomly place it somewhere else on the board.
If you moved a mine, recalculate the neighboring mine counts.
Hopefully that description makes sense when you take a look at the code, but definitely leave me a comment if you found any of it confusing.
Conclusion
I know you’ve all been waiting eagerly in anticipation for over a year for me to revisit minesweeper, so I’m really happy for you guys. You can all rest easy at night knowing that some random code has been made better. Of course, I also hope this was instructive to some of you.
As always, subscribe to see more brutal takedowns of my haters.
We may be running out of toilet paper during this pandemic, but there is no shortage of news. Each day new reports come out, and we feel like we have to be the first to soak up everything.
And we have so many questions. What’s going on? Should we wear masks? When will normal life return? Is the government infringing upon civil liberties? Who is to blame?
We want to be informed, and we want our friends to know we are informed.
Fortunately, there are plenty of experts ready and willing to share information that will completely confirm our prior opinions.
Perhaps being locked up in our homes is making us crave more information from the outside world. It’s possible, but I really don’t think this is something new. As technology has advanced the news has come at us at a faster and faster pace. With the internet now living in our pockets, the latest news is always just a glance away.
I see some problems with this. So much so that I’m going to try to convince you to stop reading the news. Or at least, cut back and be more diligent about your news consumption. It’s something I’ve been doing lately, and I’ve found it to be a positive change. I’ll share a few reasons why.
It’s Low Quality
News is cheaper to produce than ever before. This has led to a reduction in its overall quality. There are people whose job it is to write thousands of articles a year. This means they are writing multiple articles every single day.
It takes me several days of work just to crank out one JavaScript tutorial, and when I finish I’m still worried that I’ve left out an important detail or described something poorly. Now, lots of these people are probably better and faster writers than I am. But there is no possible way most of them have spent the time to understand each of the subjects they are covering at a deep level.
It’s Not Designed to Help You
By and large, today’s news is designed to produce outrage and confirm your biases. There are some exceptions, but news is mostly free. This means the advertisers are the customers. That makes you the product. And what the advertisers want is as big an audience as possible. Nothing draws bigger audiences than outrage inducing headlines and information that you can rub in the face of the “other team” on Facebook.
A disturbing result of this is that it leads to living in an echo chamber. What feels like staying informed is often just indulging in the most extreme stories and explanations that confirm your prior beliefs. Before long you’ll start viewing half the country as evil, when in reality most of them are probably a lot like you.
Of course, some stories really are egregious and deserving of our attention. Being outraged about true injustice is a healthy response. But when you find yourself getting worked up every single day over people you’ve never met, I’d say it’s time for some self-reflection.
There are Better Ways to Spend Your Time
I’ve been thinking about opportunity cost a lot lately. It applies to so many things in life, and news consumption is no exception.
You should stop to ask yourself some questions about the news you are reading. Will it be important to you two weeks from now? Will it help you make better decisions? Will it bring you peace? In short, are there other things you should be spending your time on?
It’s a good thing to stay informed of and connected to the world around you, but be wise about how you do it.
Prefer actively creating over passively consuming. Read time-tested content that adds value to your life. Read content from authors and journalists who have earned your trust and respect. Read content that will nudge you to think for yourself.
If you’re like me and struggle to get through even one book in a month, maybe we have no business consuming the junk food of today’s news.
Since I have the best readers in the world, you’re all probably asking the obvious, though slightly cynical question.
“So, should I stop reading your blog?”
To that I say, if my writing isn’t adding value to your life, then yes. Ironically, by taking my advice, you’ll be proving that it is. So actually no, you should probably subscribe 😜
I recently ran into a problem that compelled me to store some configuration data in a JSON object. The data wasn’t likely to change very often, but I didn’t want to hard code it in the application code. Unfortunately, there was not a good external data store immediately available to me for this kind of use case.
The search for a good solution led me to an idea. Could I store JSON in an environment variable? It turns out I can. I’m still not convinced it is the best solution, but it certainly has been a useful one. It at least allows me to change the configuration data without changing the code artifact. If you’ve worked in a web development or devops role long enough you’ll recognize the value of this.
The first problem I ran into was the raw JSON data breaking the config file. The JSON object has lots of special characters in it. These characters caused things to break when I tried to set the environment variable on the Linux server to the raw JSON string.
After a bit of thought I came up with the obvious solution: get rid of those stupid characters. Unfortunately, those characters are kind of important. I couldn’t just remove them.
What I could do was represent the data differently. I minified the JSON block and then base64 encoded it. That took the data from looking like this:
When the JSON data only consists of alphanumeric characters it becomes a lot easier to work with. My application code can now read it from the environment variable and base64 decode it on the other side.
I thought I’d share this pattern in case it becomes useful for anybody else. In the past I’ve also used base64 encoding to pass image byte data across the internet. It’s a handy little technique with various applications. You do have to be careful with the size of the data though.
Now, go leave me a comment telling me why storing JSON in an environment variable is a horrible idea and subscribe so you can offer similar criticism in the future.