## Advice To A New SEO-er On Picking The Best CMS

It doesn’t matter what CMS you use. Use whatever CMS you like, and learn to SEO it!

## Coding Fun: Vigenere Cipher Encryption/Decryption

I was working on some fun LeetCode type questions, and I came across a challenge to replicate the Vigenere cipher encryption and decryption in Python.

In short, the Vigenere cipher allows one to encrypt and decrypt a message if the user knows an alphabetic key. It’s notable for being easy to use; encryption and decryption are done by overlaying the key next to the message, then shifting the message letter by the letter number of the overlaid key. For more information, see the Wikipedia page discussing the Vigenere cipher .

The below functions are the “know-your-number-theory” / expected versions of how to encrypt/decrypt, where c is the encrypted message to decrypt, m is the unencrypted text to encrypt, and keyword is the secret encoding key.

``````
def vigenere_decrypt_cipher(c: str, keyword: str) -> str:
keyword_repeated = (keyword * (len(c) // len(keyword))) + keyword[:len(c) % len(keyword)]
plaintext = ''
for i in range(len(c)):
if c[i].isalpha():
shift = ord(keyword_repeated[i].upper()) - ord('A')
if c[i].islower():
plaintext += chr((ord(c[i]) - ord('a') - shift) % 26 + ord('a'))
else:
plaintext += chr((ord(c[i]) - ord('A') - shift) % 26 + ord('A'))
else:
plaintext += c[i]
return plaintext

def vigenere_encrypt_message(m: str, keyword: str) -> str:
#filter to kick out spaces and punctuation
filtered_m = ""
for toon in m:
if toon.isalpha():
filtered_m = filtered_m + toon
else:
pass
#the rest to process the "real" stuff
m = filtered_m.upper()
keyword = keyword.upper()
encrypted_message = ''
keyword_repeated = (keyword * (len(m) // len(keyword))) + keyword[:len(m) % len(keyword)]
for i in range(len(m)):
char = m[i]
if char.isalpha():
shift = ord(keyword_repeated[i].upper()) - ord('A')
if char.islower():
encrypted_message += chr((ord(char) - ord('a') + shift) % 26 + ord('a'))
else:
encrypted_message += chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
else:
encrypted_message += char
return encrypted_message.upper()
``````

Honestly, while it was fun to implement, it’s not immediately obvious how Vigenere’s works from the code. So for fun I wrote the functions below, which sort of mimics how Vigenere messages would be coded/decoded by hand:

``````
def look_up_letter_index(letter):
alphabet = "abcdefghijklmnopqrstuvwxyz".upper()
return alphabet.find(letter.upper())

def decrypt_vignere(encrypted, key):
translated = ""
alphabet = "abcdefghijklmnopqrstuvwxyz".upper()
print(len(alphabet))
count = 0
alphabet_array = []
for letter in alphabet:
single_line = alphabet[count:26] + alphabet[0:count]
alphabet_array.append(single_line)
count = count + 1
print(alphabet_array)
print(look_up_letter_index("a"))
overlaid_key = key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
encrypted_count = 0
for encrypted_letter in encrypted:
print("encrypted letter" + encrypted_letter)
print("keyoverlaid letter" + overlaid_key[encrypted_count:encrypted_count + 1])
encrypted_index = look_up_letter_index(encrypted_letter)
overlaidkey_index = look_up_letter_index(overlaid_key[encrypted_count:encrypted_count + 1])
encrypted_count = encrypted_count + 1
print(encrypted_index)
print(overlaidkey_index)
#loop through alphabet array
single_alphabet_index = 0
for single_alphabet in alphabet_array:
single_alphabet_letter_test = single_alphabet[overlaidkey_index:overlaidkey_index + 1]
if single_alphabet_letter_test == encrypted_letter:
print(single_alphabet_index)
print(alphabet[single_alphabet_index:single_alphabet_index + 1])
translated += alphabet[single_alphabet_index:single_alphabet_index + 1]
single_alphabet_index = single_alphabet_index + 1
print(translated)
return translated

def encrypt_vignere(message, key):
alphabet = "abcdefghijklmnopqrstuvwxyz".upper()
print(len(alphabet))
count = 0
alphabet_array = []
for letter in alphabet:
single_line = alphabet[count:26] + alphabet[0:count]
alphabet_array.append(single_line)
count = count + 1
print(alphabet_array)
print(look_up_letter_index("a"))
overlaid_key = key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
overlaid_key += key + key + key + key + key + key + key + key + key + key + key + key + key + key
message_count = 0
encrypted_message = ""
for message_letter in message:
print(message_letter)
overlaid_key_letter = overlaid_key[message_count:message_count + 1]
print(overlaid_key_letter)
message_letter_index = look_up_letter_index(message_letter)
overlaid_key_letter_index = look_up_letter_index(overlaid_key_letter)
translated_letter = alphabet_array[overlaid_key_letter_index][message_letter_index:message_letter_index + 1]
print(translated_letter)
encrypted_message += translated_letter
print("--")
message_count = message_count + 1
print(encrypted_message)
return encrypted_message

print(encrypt_vignere("MESSAGE", "SECRETKEY"))

print(decrypt_vignere("EIUJEZO", "SECRETKEY"))

``````

While these functions are much longer, I think they’re much more readable than the previous set of functions. These versions generate a matrix of 26×26 alphabets; the first row is a to z, the second row is shifted 1 to the right (b to z then a), the third row is shifted 2 to the right (c to z then ab), etc. Then we overlay the secret key and use it along with the message/encrypted message to encrypt/decrypt by finding the appropriate entry in our matrix. Admittedly the code is a little ugly and could be cleaned up, but I thought it would be fun to share.

## Review: Finding A WordPress Theme For A Tumblr/Tumblelog -Style Blog

Summary: If you’re exporting your blog from Tumblr to WordPress and want a Tumblr style theme, I recommend Nucleare or Twenty Fifteen.

I’ve recently helped export some blogs off tumblr to a WordPress installation. Tumblr is a great blogging platform – it’s terrific for quickly posting those random thoughts, code samples, and images one sees across the course of the day. But WordPress is a better long term solution, especially for blogs that are quickly growing.

The hardest part of exporting a Tumblr site to WordPress is finding a theme that replicates the clean, neat design of Tumblr. I used to recommend a theme called Fast Blog (\$44 from ThemeForest). Unfortunately, the theme is no longer available and in any event hasn’t been updated in years.

A friend of mine recommends Annina, which uses a big left navigation bar with a Pinterest-style multiple stacked boxes for each blog post:

Annina is a good, basic theme that is fantastic for mobile devices: it’s easy for the navigation bar and post “boxes” to rearrange themselves to fit different mobile (tablet/phone) sized screens – a lot of blogs and sites are rearranging themselves to fit this aesthetic to earn those mobile views.

The basic version of Annina is free, but there is a paid version of Annina that unlocks additional features. If you’re a new blogger, the free version of Annina is more than enough.

Annina is a good theme, but my major complaint is that I want whole blog posts to show on the blog’s main page, not just the excerpt that Annina shows – just like Tumblr does.

### My Picks

If you’re exporting a Tumblr website to WordPress and need a similar theme, I recommend either Twenty Fifteen or Nucleare.

Why Nucleare? It’s a crisp, clean theme that echoes the general lines of Tumblr, yet offers a reasonable amount of customizability.

Perhaps my only complaint with Nucleare is the tons of wasted space around the title section and the inability to set the page width (I think it’s too wide on desktop displays). Otherwise, it’s a terrific theme that replicates the Tumblr experience.

In the Appearance > Customize section of WordPress admin, you can change the theme colors and (even more importantly in my view) change how posts are shown on the main page: either excerpt or the full post:

Another theme I would recommend is Twenty Fifteen. It’s the WordPress default theme from 2015, but it’s been updated by the WordPress folks to maintain good SEO and mobile performance. For the screenshot below, the only change I made was to alter the navigation bar background color to blue (hex code #1287a8; default for the theme is to leave it white).

Perhaps my only complaint with the Twenty Fifteen theme is that it includes a lot of padding and margin space around posts. I may end up cutting down that space using additional CSS.

So bottom line: Use Nucleare or Twenty Fifteen for those Tumblr blogs moving to WordPress. Both themes are free and have excellent defaults, along with good customization out of the box.

## Lottery Error Message & Consultant Thoughts On Food

I love collecting samples of error messages, especially branded error messages. Today’s sample comes from the Illinois Lottery website – or to be more exact, their iOS app which frames a web page:

As I’ve discussed before, I’ve spent quite a few years as a consultant – while working as a consultant, I loved staying at DoubleTree hotels: their prices were fair, with good amenities targeted towards business travelers. That’s why I’m pleased to see that DoubleTree recently published their recipe for cookies – they were always a tasty treat when checking in.

Speaking of recipes, I’m also pleased to note that Chipotle published their recipe for guacamole. I enjoy eating at Chipotle when I travel: it’s a good, healthy helping of food in an easily portable burrito.

## Tumblr Sale

News came out recently that Verizon’s Oath unit (which is partly made up of Yahoo’s web assets) sold Tumblr to Automattic (they develop WordPress and run WordPress.com) for \$3 million.

Obviously, this is a big drop from Yahoo’s original \$1+ billion purchase, but there’s still quite a lot of value to be salvaged from Tumblr. This HN discussion comments that Tumblr is still receiving 2.5+ billion page views per month, which doesn’t even include their mobile views. I see a lot of articles moaning about Tumblr’s problems, but it is still a powerful brand and I’m quite surprised another company didn’t buy it up – \$3 million is a firesale price.

Of all the articles discussing Tumblr’s sale, I like this one the best: a post from one of VCs who originally invested in Tumblr. Regardless of what happens to Tumblr, I think it will be remembered as one of the first places to easily and quickly share thoughts, a place which made it easy to create communities and fandoms, and a surprisingly upbeat and positive place compared to other social media sites.

## Using The Good Parts Of AWS

There was a fascinating Twitter thread on how to use the “good” parts of AWS, from an ex-AWS engineer:
https://twitter.com/dvassallo/status/1154516910265884672 . Click to expand the below image.

Bottom line: He recommends building your services to use AWS EC2, DynamoDB, etc but avoiding abstractions such as Lambda and API Gateway. There’s an interesting discussion on this thread on HN:
https://news.ycombinator.com/item?id=20545561 .

## Cutting More Space Off The Twenty Seventeen WordPress Theme

What drives me crazy about the WordPress Twenty Seventeen theme is that it’s almost the perfect starting theme, but it wastes so much screen real estate – especially in the header.

Here’s CSS to shave off space and makes the header a lot less “aggressive” looking:

``````div.custom-header {
text-transform: lowercase;
}

div.site-branding {
}

h1.site-title {
text-transform: lowercase;
}``````

## WordPress Twenty Seventeen Theme Page Spacing

I think the WordPress Twenty Seventeen theme is pretty close to the ideal starter WP template – it’s simple yet looks very nice, especially if there’s a nice header image.

One of the major annoyances with using the theme is that there’s so much empty space in a default page. For example, here’s how my /about page looked like with just the default CSS (note how small the “ABOUT” text is, and it’s a H1 heading!):

I added the following custom CSS to help reduce the space and slightly increase the size of the H1 text:

``````h1.entry-title {
font-size: large !important;
font-weight: bolder !important;
}

margin: 0 !important;
}

div#content.site-content {
}``````

## IBM Watson Natural Language Understanding

I was fiddling with code that worked with IBM Watson’s Natural Language Understanding API, and kept getting the following error:

``````{
"error": "invalid request: content is empty",
"code": 400
}``````

What happened is that I was calling out to IBM using the following requests Python code (post_data represents a Python object being encoded to JSON):

``````post_data_string = json.dumps(post_data)
requests.post(endpoint, data=post_data_string, timeout=45, auth=(ibm_user, ibm_pass))``````

However, it seems that the API insists on having the correct request content type set; i.e. you must set Content-Type: application/json for the IBM Watson servers to notice there is a data body in the POST request. I fixed it by using the json parameter – the requests library for Python automatically inserts the application/json content type when this parameter is used. If you use a different language, you’ll need to set the proper content type in the language’s preferred manner.

``requests.post(endpoint, json=post_data, timeout=45, auth=(ibm_user, ibm_pass))``