A Mac User's Survival Guide For Buying A PC Laptop

"Scream" by xuhulk is licensed under CC BY-SA 2.0.

Why Are We Here?

Mac users tend to be a rather opinionated lot. We generally love our Macs for all kinds of reasons - the interface, the hardware, the polish - the list goes on.

But life is complicated, and there are all kinds of situations that might make a dyed in the wool Mac user choose to buy a PC laptop.

For myself, the motivation was simple. Apple had about a 5 year stretch where they manufactured nothing but epic turds for laptops. I don't choose such a vulgar turn of phrase lightly. As someone who has literally been a Mac fan for decades (My first Mac was a Motorola 68XXX CPU based Quadra tower. Yes I'm old) I was appalled at how far the quality had fallen. I won't go into it here as that's not the point of the article, but let me just offer this one hint: Butterfly keyboards.

So anyway, the pandemic was just starting to kick up and I realized that I REALLY needed a personal laptop. So here we are.

This isn't going to be exhaustive, I'm just going to cover some of the more salient points you may not have been aware of, having lived the sheltered Mac life as I did :)

Also note these are my opinions. I'm not by any means an expert, I just wanted to share what I learned in hopes it might help someone.

Choosing a Vendor

Which laptop maker you choose will depend largely on what's most important to you. If ultra expandability is your think, you should probably check out Framework. If you care less about portability and want a luggable gaming rig, I'd give Alienware a look.

As for myself, I need something that would be sincerely portable, and I absolutely require a really good keyboard, as well as good warranty support because fixing it myself wasn't a thing, so I chose Lenovo.

There are plenty of other choices, but hopefully this will at least get you going.


One of the biggest nasty surprises I was in store for in my PC laptop buying experience was the screen. Mac laptops have, near as I can tell, always shipped with gorgeous, bright, high resolution screens.

This isn't always the case in the PC world, so if you're like me and picky about screens (in my case, I'm low vision, I NEED a large bright display), you need to be careful here.

To Matte or Not To Matte

Every time I mention nit count and screens, people who likely know more than I do about this stuff remind me that having a Matte screen can make a significant impact on the amount of perceived glare. That makes sense to me, but I have yet to have the opportunity to test matte and non matte screens side by side so I have no personal opinion on this. If I ever buy a PC laptop again though, I'll be sure to look for a matte screen. With glare being such a serious problem for me, it certainly can't hurt!

It's All About The Nits

The Lenovo T15 gen2 I bought is a lovely laptop in many ways, but the screen is totally unsuitable for me. At 15" and 300 nits, the display always leaves my eyes straining and can't handle use in outdoor daylight situations at all.

This is a deal breaker for me, so if it is for you, be sure to pay attention to how many nits your display has and whether or not it's big enough for your needs.

There are PC laptop models out there that match the 1000 nit gorgeousness of a Mac laptop's screen, you just need to be sure the one you pick is one of those models :)


As consumer demand has driven vendors to make laptops thinner, their keyboards have, in my opinion, suffered. Thankfully Lenovo realized that not everyone is willing to live with a mushy keyboard with no key travel, so their Thinkpad line all have keyboards ranging from good to excellent. The keyboard on my T15 was quite good with nice key travel and just enough tactile feedback to let my wrist know it can stop pressing. I tend to unfortunately CAVEMAN SMASH mushy keyboards, and then it hurts :)

Alienware laptops also generally have superlative keyboards, but as I said those are often more luggables than truly portable, so, it's all about the trade-offs :)

Unfortunately, it's very hard to shop for a keyboard that fits you through the mail. You may need to phone a friend or find a local computer store where you can actually lay hands on that model laptop to try it out yourself.


Be sure you get any adapters you'll need. PCs are more likely to have DisplayPort ports for monitor / video connections than HDMI, so you may need to go buy an adapter for your monitor.

You'll also likely see an actual wired network (Ethernet) port, because unlike Apple, PC vendors recognize that in many places wifi is dodgy as heck and having a wired network connection can be a godsend.


If you're like me, when you buy Apple hardware, you ALWAYS buy Applecare to go with it.

Be careful about your laptop of choice's warranty options. One thing I really like about Lenovo in this regard is that they have good warranty service and the warranty attaches to the machine, not the person, so if you want to sell your laptop, the warranty travels right along with it.

I've seen several laptop vendors offer a 1 year parts and labor warranty by default, and that's it. I generally like to be sure I can get more out of my investment than that, but opinions vary on whether or not warranty service is a good idea. Just bear in mind that if you don't have one and you break it, you'll need to either fix it yourself or hope for the best at a local computer repair shop.


Now that Apple has gone back to making excellent laptops, I don't see myself buying a PC for myself in the near future, but having done it once, if I ever do again at least I'll know what to look for. I hope this helps you make a purchase you're happy with.

Whatever you choose, have fun and happy computing!

Windows Papercuts for *NIX Developers


If you're used to developing on *NIX systems, coming to Windows can be a bit of a shock.

My goal in writing this article is to point out some of the pain points and, where I know they exist, some work-arounds.

Note that I'm talking about native Windows here. If WSL meets your needs and your environment allows it (not everyone's does. Many IT orgs turn it off) then bully for you but this article isn't about that :) I think WSL is both an incredible tool for developers and an awesome feat of engineering. I wish more Linux folks appreciated this. Anyway :)

So let's get started!

The Paper Cuts

The C Compiler

For most of us, having a standard raft of development tools on hand is par for the course. We just expect gcc and make to be there at our beck and call, and the fact that they're not can cause some tools to fail spectacularly.

For instance, whenever I start my editor of choice (Neovim) I'm greeted with:

Neovim C Compiler Error on Windows

Having spoken to some experts, apparently it's considered really bad form to leave your C compiler on the PATH on Windows. I suspect this is because malware on Windows is such an incredibly pervasive problem.

I get that, but then we should probably either modify our tool-chains to not expect that as a default or maybe create documentation to help people understand the happy path.

As near as I can tell, the 'standard' set of c/c++ tools on Windows is Microsoft Visual Studio. The free "Community" version works just fine though the installer is a bit of a jank-fest.

That thing provides a prompt shortcut called "Powershell for VS XXXX" and you can use that to get a shell that has the usual build tools available.

Not a great solution though, since the experts say not to run that way as a default, but having your editor blow up on start just-up isn't a great feel.

The Shell

While you certainly can run tools like bash or zsh on Windows, unless you really know what you're doing, this is not the happy path. You're in Rome. Do what the Romans do and you won't regret it :)

The good news here is that the native tools are now really quite good. Gone are the days when CMD.EXE was your only choice. You now have Powershell and it's really quite awesome.

Here are a couple of tips to make your Powershell experience awesome and help you appreciate what this environment has to offer.

Oh My Posh

This one's gotten a lot of press and let me tell you it's incredibly well deserved. It's like the oh my zsh of Windows shell prompts :)

Mine shows me git status and whether my last command's exit code indicates success or failure, as well as what Git branch I'm on. Here's what it looks like:

What My Oh My Posh Prompt Looks Like

I wrote some about Oh My Posh in my previous article on Windows for Python Developers.


One of the biggest productivity boost for me in recent memory was when I integrated fzf the fuzzy finder into my workflow.

With a single keystroke I can find any file or directory on my system. Navigation becomes effortless and the endless sequence of cd and pwd commands melt away in a burst of productivity goodness :)

Thankfully, Powershell offers all these benefits as well via PSFzf.

Here's what it looks like. In this case I wanted to edit my Neovim main configuration file init.lua:

Edit my init.lua file

The Console / Terminal

For long time *NIX users, one of the biggest bones of contention for a long time was the Windows console. To put it kindly, it was god awful, mostly because it maintained compatibility with the Antideluvian DOS console.

Happily, we now have a fairly decent solution Windows Terminal. I say fairly decent because it's still not quite up to par with your favorite NIX terminal, but the fine folks behind this open source project are working really* hard to change that, and the progress they've made here has been nothing short of miraculous. Mad props to these folks for fixing by far the biggest deal breaker for many around working in Windows!

They've even recently added an easier UI for editing settings, but you can also still go edit the JSON yourself if that's your jam :)

It's not perfect, but this is an incredibly flexible tool with a ton of depth and it's been exciting to watch it evolve.

The Windows Desktop/GUI

I'm sure there will be folks who aren't happy with this one but my take? Just ignore it.

Windows is pretty good about making EVERYTHING accessible from the keyboard, and many things are also accessible from the command line. If you just avoid graphical interfaces wherever possible, and if you're anything like me, you'll see your productivity levels soar and your frustration levels plummet.


One of the big pain points coming from *NIX is the lack of a 'real' package manager.

I use the winget tool that comes bundled with Windows 11. It's officially supported by Microsoft and lets me install most if not all of the commercial apps I use.

It has the further advantage that it will write a JSON blob with all the packages you have installed, so you can get your software up to snuff with a single Powershell invocation.

But there are other popular options as well, namely Scoop and Chocolatey.

To be honest I wish MSFT had worked a bit harder to maintain compatibility with these other projects so we don't have multiple separate package namespaces. Can't have everything I guess.

Where Do I Put?

One of the things I continue to struggle with is the simple expedient of "Where do I PUT things?". On UNIX based systems, pretty much everything user or configuration related lives in $HOME. Not so on Windows.

As just an example, my Neovim configuration lives in something like $HOME\AppData\Local\nvim.

In some respects, I get it. Keeping application configuration separate is a good thing, but navigating where to put what can feel like a bit of a morass for the uninitiated.

Maybe once I get a better understanding of the lay of the land, I can create a cheat sheet for UNIX users.


That's all I have for now, but I may update this post as time permits or if various situations I detail here improve. Thanks for reading!

Hacking the Wetware 2 - Antipatterns (Burn Out & The Ego Trap)

"Boiling Frog" by DonkeyHotey is licensed under CC BY-SA 2.0.

Of Burn Out And Boiled Frogs

I can't speak for everyone, but as for my own experience, burn out can be tough to self diagnose because it happens slowly, by degrees.

It's a state of mind where pushing yourself even a little bit, even to do the things you'd normally do as a matter of course, feels incredibly difficult. It's that feeling of knowing you need to do something but being unable to actually complete the thoughts or actions necessary to actually get it done.

Often, at least for me, it's a result of having to perform the same set of tasks over and over again in a stressful situation.

Human brains simply weren't designed to be subjected to a constant diet of stress combined with cognitively challenging tasks and an overall lack of novelty or variation.

Understanding this can go a long way for preventing it, but even so, especially in the technology industry, it can happen to anyone.

Changing things up with your work load can sometimes help, but other times the source of the stress or conditions around your work mean that even varying your worrk may not be enough.

There's a really superlative book on this topic I can strongly recommend - Why Zebras Don't Get Ulcers.

How Does One Un-Boil a Frog?

There are a few things I have found to be helpful through the years in recovering from burn out.

Do Something Fun & DIFFERENT. Pick Up a New Hobby!

As a part of recovering from my most recent bout of burn out I've started learning how to play the piano/keyboard. A key aspect in this being effective is that it's something VERY different from the activity that got you here. For me, learning an entirely new skill that has nothing to do with computers has been satisfying and fulfilling.

Tech projects can be good too provided they're well and truly disconnected from the work that's burning you out and don't end up being a source of stress themselves!

Why not go for some long walks/hikes in the woods? Go for a nice bicycle ride? Finding fun activities that are also exercise can be good on many levels!

Give Yourself a Break

As professionals we put a ton of pressure on ourselves. Everybody wants to be a superstar and nobody likes to think about losing, even when losing a tiny and actually almost meaningless skirmish can feel like you've lost the war.

It can be difficult to zoom out and gain that perspective in the moment, but it's important to try and figure it out. Having solid support systems can be very helpful here, whether it's your spouse, a good friend, or even a therapist. Speaking of...

Get Help If You Need It

Many of us were raised to think of therapy as a thing for "crazy people" - that nebulous other that SURELY isn't us! We're stronger than that and more self sufficient.

Except, when push comes to shove, we're all human. We all need mechanisms in our lives to help provide balance and an outside perspective to keep us grounded and help avoid boiled frog syndrome.

I myself use BetterHelp and have found it incredibly useful.


This may sound a bit wu or perhaps irrelevant to some, but I have recently found it to be a powerful tool for shaping the way I think about things in a positive direction.

Taking a moment to zoom out from whatever I'm thinking or feeling and appreciate the fact that I live a life of such incredible privilege helps me gain some much needed perspective.

Clearly I'm not the only one, I found this Youtube video on the topic really helpful.

The Ego Trap

There's something else I want to talk about. This may not apply to you, but if it does, maybe I can help.

Many of us who work in technology take a lot of pride in our work. We may even, if we're lucky enough to go to work for what some might consider an 'elite' company, attain positions with a fair bit of cachet in the industry.

This can create yet another variety of boiled frog - the ego trap. Where your very identity becomes bound up in your job. It's not just "I work for BigCo" - it's "I AM BigCo".

I can't imagine that anyone who's fallen for this would even admit to it in the moment. It's the kind of clarity many of us only get when our situation changes out from under us and we're forced to confront an unpleasant reality.

Remember, no matter how excited you are to be working for any particular company at a particular job, at the end of the day it's JUST a job.

Cliches about health being the only thing that matters aside, this situation can create some incredibly intense tunnel vision:

"I WILL find a way to maintain the status quo!".

Thing is, maybe you Can't and moreover maybe you shouldn't! For your own sake and perhaps for that of your employer.

Sometimes, the only winning move is embracing your limitations and accepting that you can only do so much so fast.

I don't mean to say that one should just meekly accept defeat, but sometimes winning is having the wisdom to tactically retreat and formulate a better plan for success :)

Skills can be built upon and improved, and taking ownership of that process and the will to make it happen can itself be incredibly empowering!

Mis-Adventures In GatsbyJS

Key West Octopus by oe Parks is licensed under CC BY-NC 2.0

Over the last few years I've been feeling like living exclusively in my Python programming happy place is something I can't afford to do.

Setting The Scene

It's almost impossible to ignore the rise of JavaScript in our industry. What started out as an extension project for Mozilla has grown into an ecosystem with more tentacles than an H.P. Lovecraft novel.

So while there are aspects of the language that I find very uncomfortable to work with and that seem to be a bad fit for my brain, I feel compelled to give JavaScript a fair shake and make a point of using it "in anger" in an actual project that I can ultimately get something out of beyond just learning and keep using and maintaining over time.

For the last few years I've been running my blog on Pelican a beautiful Python based static site generator which has one of the most elegant and easy to understand and modify code bases of any open source project I've ever used.

However, Pelican's minimalist DIY spirit was forcing me to come to terms with an ugly reality I was loathe to admit: I know absolutely nothing about modern web development!

Sure, I've been able to cobble together simple HTML pages for years. Nothing difficult or involved there, but there is a very long way between being able to add some HTML tags to a text file and producing a website that people will actually want to visit in 2022.

O.K. This smells like an opportunity to lean into the discomfort and grow some new skills so I can hang out a shingle worthy of my brand in full tilt 2022 adaptive web style.

Enter The Great Gatsby(JS)

On the face of it, there's a lot to like about GatsbyJS. Here are a few things I found particularly attractive going in:

  • Layout will adaptively resize itself depending on the format and characteristics of the viewer's browser
  • Sites written with GatsbyJS degrade gracefully and work fine even when people have JS turned off
  • Site components communicate using an GraphQL back-end

So, I dove in head first and started working through the tutorial which, helpfully enough, shows the developer how to build a rather nice, feature-ful blog complete with rich tags support and an elegant navigation system.

And I've gotta say, the tutorial was a really good experience! Want to build an index page? Great! Write some JSX that queries the GraphQL back-end using a fairly elegant syntax that embeds the query right into the page. The query returns your post list which your page then renders. Hey this is pretty cool!

Here's what that first page looks like so you can get the flavor:

import * as React from 'react'
import { Link, useStaticQuery, graphql } from 'gatsby'
import {
} from './layout.module.css'

const Layout = ({ pageTitle, children }) => {
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {

  return (
    <div className={container}>
      <title>{pageTitle} | {data.site.siteMetadata.title}</title>
        <ul className={navLinks}>
          <li className={navLinkItem}>
            <Link to="/" className={navLinkText}>
          <li className={navLinkItem}>
            <Link to="/about" className={navLinkText}>
        <h1 className={heading}>{pageTitle}</h1>

export default Layout

A couple of weeks of evening spare time (probably a couple of days of wall-clock time - bear in mind I'm teaching myself JavaScript as I do this) - I finished the tutorial and deployed my new blog. I was elated! Mission accomplished!

The Plot Thickens

The next day, after I'd triumphantly posted the URL for my shiny new redone blog to social media, the first fly appeared in the GatsbyJS soup manifested.

A friend rather understandably said "Hey, I use an RSS reader to keep up with blogs. You used to have an RSS feed. What's the URL for the new site?"

Uh. Woops. Truth be told I hadn't even thought about that, and the tutorial doesn't mention it. That's pretty understandable too, right? You don't want to overwhelm people who are trying to adopt your technology with a firehose of details to master when they're just starting out.

OK. Let's bring up GatsbyJS's (up to this point) excellent documentation and see how we add an RSS feed...

The Abstractions Begin To Crumble

Right then. I find a page describing how to add an RSS feed to your blog, Just add this handy dandy plugin to your site. This will let you do a similar GraphQL query to the one you used for your post list, only this time you'll be generating your RSS feed. Here we go!

Add the plugin and BOOM! My site build fails with an utterly inscrutable Webpack error. Why? Ah the plugin was for a prior version of GatsbyJS and isn't compatible with the one you used to build your site. OK, let's just use that older version of GatsbyJS instead!

Well crud. Turns out that the tutorial was written using MDX, a JSX flavored version of the popular Markdown mark-up language for React JSX pages, and the plugin used to provide MDX support both doesn't work with the RSS feed plugin and doesn't run in the prior version of GatsbyJS.

I said I wanted to learn. Let's roll up our sleeves and see about porting that plugin to the new GatsbyJS version.

Three agonizing weeks of pointless struggle later...

The Knee Bone DOESN'T Connect To The Shin Bone

One of the things that drew me to GatsbyJS to begin with was this beautiful abstraction: pages, plugins, and components all seamlessly interpolating with a GraphQL back end.

And it does work that way to an extent. All the plugins do indeed communicate with the rest of your system using GraphQL queries, but because the plugin architecture doesn't seem to enforce any interoperability rules, and also because successive GatsbyJS versions introduce radical breaking changes to the plugin API, you end up with a programmer who was sold a glorious GraphQL future but winds up holding a rather large bucket of bolts that refuse to work together to build a meaningful whole.

To Be Fair

I realize I'm painting a rather unappealing picture of GatsbyJS here, so I just want to say that it became a rather popular JavaScript framework a year or so back with good reason. There are many many competent programmers out there deploying beautiful sites that scale using these tools.

I also recognize that building abstractions that don't leak and that seamlessly work well together is incredibly challenging. I just feel that ultimately GatsbyJS isn't the tool for me and also that perhaps sme of the marketing should be adjusted to reflect reality on the ground.

It also needs to be said that GatsbyJS is 100% FLOSS, and as such is a gift freely given by its implementors which I very much appreciate. None of what I write here changes that in any way.

I should also say that my inability to build with it is as much due to my own lack of JavaScript acumen as it is with the tool itself.

These are just my opinions and personal experiences and thus should be taken with a grain (or perhaps a shaker) of salt, especially if you're a seasoned JavaScript developer.

The Happy Ending (But Not With GatsbyJS!)

Ultimately, I decided that the best thing I could possibly do for myself with this blog project was to go with what I know, so I chose Nikola - a superlative Python powered static site generator, and I'm just delighted with that choice.

I'm still planning on finding something to use JavaScript for, it's just not going to be this particular task :)

A Teency Bit More Housekeeping

I'm switching the static site generator I ues for this blog from Pelican to Nikola.

There are a number of reasons for this - better/more theme options, a more active development community, and some really swank features I just love.

The up-shot however is that the RSS feeds will need to change. The new links are clearly signposted on the header at the top of the blog.

Also, I've switched the comment system from Disqus (Which I really Dis-like :) to Intense Debate which I've been using on my personal blog and love to bits.

You can find the old Disqus comments here

Thanks for understanding and updating your feed readers!

Some Brief But Important House Keeping

Hi all!

Just a brief house-keeping note.

This is going to hence-forth be strictly my professional blog.

I'll be cleaning out old posts that aren't tech related and maybe moving any I feel particularly inclined to keep over to my new personal blog, Playing With Quicksilver.

I'm not trying to hide anything, so feel free to browse my old posts via the Wayback Machine over here.

I look forward to blogging here more often! I'll likely also be switching to the Nikola static site generator because it offers a number of features and creature comforts that will make my life easier (Like having a command that will pre-seed a new post with all the right metadata fields. Yay :)

As always feel free to hit me up here or on social media if you have any thoughts.


Getting Started With Python On Windows 2021 Edition: Push The Easy Button!

Don't Despair! This Is Gonna Be Easy! :)

Over the last few months I've seen a ton of confusion swirling around social media about how to help people who are new to Python development and software development in general get up and running on Windows quickly.

GOOD NEWS! You can ignore all that. Many of these suggestions are well meaning but come from people who don't actually do Python development on Windows regularly.

Note that I'm not going to tell you the 5 different ways to do a thing, I'm going to tell you the ONE easy way :)

So let's get started!

Side Note: Everyone Will Tell You To Use WSL - You Probably Don't Want That!

I hear a lot of incredibly talented and experienced well meaning UNIX/Mac enthusiasts tell newcomers looking to get going on Windows "Oh well you just use WSL! It's easy! Then you install python with apt get yada yada, and then you install pyenv, and then you configure your shell's environment to use the right shims... and..."

The truth is that if you want to learn Linux - you SHOULD! It's an incredible platform and a virtually bottomless font of power waiting for you to tap.

But if there's one thing I've learned in 30 years in the tech trenches, it's that trying to learn a million things all at once is the surest way to learn nothing. Why not focus on teaching yourself Python programming first and then exploring Linux as a separate effort?

Install Python

If you're on Windows 11 (And I recommend it if your hardware is new enough!) this is as simple as bringing up a Powershell in your swank Windows Terminal. If you want a look at my setup please go read my article on that.

Anyway, all you have to do is type:

winget install python

That's it! This will install the latest stable version of Python from The official Python website. If you're not lucky enough to be running Windows 11, just download the latest stable version from the website's Downloads page and double click on the executable file in your Downloads folder. If you're not sure just keep clicking Next on the dialogs and in a few minutes you'll have Python installed!

Embracing The Power of Py! (Psst. This Is The Easy Button!)

The 'py' Python launcher used to be a super power that only Windows versions of Python shipped with, but now thanks to Brett Cannon, an amazingly prolific Python core developer's hard work our UNIX friends can enjoy the easy button as well!

So let's get this party started and see how easy it is these days to get into the Python prompt:

Windows Python Prompt With Py

Pretty easy, right?

Note that py has other superpowers as well. It can list all the python versions you have installed, and also let you choose which version to run with the arguments you choose. Run:

py --help

to see an exhaustive description of all the magic tricks py can do :)

Set The Stage

Again, from your Powershell, create a project directory for yourself. Programmers often create a 'src' directory wherever it's convenient (Maybe in your home directory?) and then put their projects underneath.

So let's go ahead and do that:

mkdir src\starwars_characters

# Yes i'm a big nerd. Our project will pull down a list of characters in the movies from the Star Wars API :)

cd src\starwars_characters

Building A Sandbox

Now let's create a safe space for our project so we don't unintentionally install libraries or other experiments in public. This can lead to situations where you go to create another project but a library you installed previously either causes undesirable behavior or perhaps is even in a broken state, getting in the way of you getting your work done.

We're going to create a thing called 'virtual environment'. Don't worry too much about the details, just think about this as a nice tidy sandbox for us to play in where we don't have to worry about breaking anything outside.

Again from our Powershell prompt:

# Actually create our virtual environment. Put the bits in a folder called 'venv'.
# Most Pythonistas use this folder name, but you can use any name you want :)
py -m venv venv

# Actually activate our new virtual environment in our Powershell

Let's see what happens when we do that (Assuming you're running Oh My Posh, and you should be if you followed my setup article):

Create/Activate Virtual Environment

See what happens there? We create the virtual environment, and our shell notices which Python version it uses, and tells us that in our Powershell prompt!

Then, we activate our virtual environment, and now our prompt adds a (venv) at the beginning. With this visual indicator in plce, we know we're safely ensconced in our sandbox and can start playing with no worries!

Install Necessary Libraries

You'll need an editor or an IDE. I use Visual Studio Code. It's free, it runs on any modern computer, and it offers an incredibly rich set of tools to help you with your development. Bonus points? It's also free, and even largely open source.

Let's get started, and tell Python which libraries we'll need for our project:

code requirements.txt

In this file, add a single line:


If you want to add a truly superlative interactive Python environment with which to prototype and explore, you could also add IPython:


(Note IPython here is case sensitive so be careful!)

Now, still in our Powershell prompt, type this command to actually install these required libraries into our virtual environment:

py -m pip install -r requirements.txt

You should see some messages about libraries being installed. Note that you invoke IPython this exact same way:

py -m IPython

Write The Code

Create a file in your project directory called starwars_characters.py with your editor that includes the following code:

import requests

STARWARS_API_URL_BASE = "https://swapi.dev/api"

response = requests.get(GET_CHARACTERS_URL)

response_json = response.json()

characters = response_json['results']

for character in characters:
    print(f"Character Name: {character['name']}")

Here's what my Visual Studio Code session looks like with this code loaded and the output shown in the run window:

Starwars Project VSCode Screenshot

Notice that bit at the bottom that says 3.10? That shows us that Visual Studio Code automatically detected the Python we have installed in our virtualenv. You can click on that to see a list of installed Python interpreters to choose from.

We can run our new project either by using the Run menu inside Visual Studio Code or on the command line with that very same py syntax we used before:

py starwars_characters.py

The End Is Just The Beginning

Well there we have it! You have Python installed and running, and you've built a small but interesting Python project right here on your Windows machine!

The truth is, a large number of people have put in innumerable hours making Python drive smooth like a Cadillac on Windows, so if you find yourself using and enjoying it, the next time someone tells you to abandon all hope and install Linux/WSL, be sure to point them at this article! Maybe if we change some minds we can help bring more Pythonistas into the incredibly awesome Python community!

Please feel free to leave comments with any questions, or hit me up on Mastodon or Twitter.

I'd love to hear from you!

2021 - The Year Windows Became a First Class Python Development Environment

[06/08/2021 Update: Added a bit about Windows Terminal. Dunno how I forgot that the first time around!]

As I've written about previously and elsewhere, I felt so badly burned by Apple's laptop hardware design decisions of a few years ago that I've rather fallen out of love with that platform for my personal work. The latest hardware is much better, but I feel like the message has been sent and received, so I'm not rushing back any time soon.

My first choice was the Linux desktop, and after months of struggling, instability and accessibility issues I'll admit I've been looking for stable, solid alternatives that are also powerful enough to get the job done and maybe even have something new to offer. As an old dog, sometimes it's really nice to be taught some new tricks!

If you've tangoed with Windows in the past, and found yourself struggling against its rather byzantine UI, I'd urge you to read on and see if maybe it's not time for another careful look.

Since choosing the right tools is all about your unique set of needs, I'll use those as categories to drive the discussion and showcase how Windows is doing a great job of satisfying them.

In The Beginning, There Was The Command Line!

One of the things that first drew me to UNIX decades ago was the shell. The ability to get pretty much ANYTHING I needed done by typing a few commands, and to create incredibly powerful mechanisms by stringing them together is downright intoxicating.

I still love me some Bourne shell, it's just as powerful today as it was decades ago. However Windows Powershell has some incredibly powerful paradigms of its own that are worth looking into.

In addition to things like object pipelines and desired state configuration that the UNIX shell simply can't do, modern Powershell has creature comforts like Oh My Posh that make for a very comfortable work environment. Here's a screenshot of mine:

My Oh My Posh Prompt

You can see that I get all kinds of nice status like exit code of last command, current git branch, current Python version and virtual environment, etc.

While Powershell is indeed a totally different beast from the UNIX shell I'm used to, its built in help for every command and understandable syntax make the learning curve feel rather shallow indeed.

Another gripe most UNIX users have when coming to Windows is that everything requires mousing around and futzing with a GUI, and it can feel like you're trapped in an endless series of installer screens to get even your basic working tools installed. Modern Windows obviates all that with winget a full fat package manager with tons of common applications already in there. Just winget install git and you're off to the races :)

Before The Command Line, There Was The Terminal

As anyone who's worked with Windows for a long time could tell you, in the old days, the Windows Console was pretty primitive. You were basically dealing with MS-DOS CMD.EXE with the barest modicum of window dressing. Needless to say, this is 2021 and that's just not cutting it.

Thankfully, there is a superlative alternative that's really come into its own in 2021 - Windows Terminal. Finally all the features anyone who's been working in the UNIX world have come to expect over the last 30 years are available on Windows as well. Multiple tabs, excellent terminal emulation, great theming and color support, and the ability to seamlessly handle different shells per tab. I regularly keep a Powershell and a WSL tab open for my work.

If you've ever struggled along with the old CMD.EXE, fighting for every cut, paste or insert, this really is a game changer.

I Hate Meeces To Pieces! (Really, Don't Make Me Use the Mouse!)

As someone who's partially blind and has fine and gross motor impairment, using the standard Windows Icons Mice and Pointers user interface is downright agonizing. I need to be able to launch apps with just a few keystrokes. On the Mac, Alfred fulfills this role admirably and adds a whole host of next level productivity power ups in addition to keyboard app launching.

A very recent addition on the Windows side that seems equally powerful and easy is Microsoft Powertoys Powertoys Run feature. I can launch apps, bind keys to actions, and access system functions like sleep, restart and the like all 100% from the keyboard. Nice!

Another Powertoys addition that's frosting my Pop-tarts is Powertoys Keyboard Manager which allows me to remaps the dread CAPS LOCK key to Ctrl so it's right next to my pinky as God Intended :)

This simple enhanment has been impossible with Windows forever without resorting to more drastic measures, so having it work pretty much out of box now is super sweet.

Python - It Takes a Cast of Thousands to Raise a Platform

If you'd uttered the words "Python" and "Windows" in the same sentence a few years back, the average Pythonista would have rolled their eyes or groaned and then proceeded to tell you a war story about how they had to spend weeks trying to get some critical module or other working.

Those days are just straight up gone. Microsoft and the Python community at large have poured countless engineer hours into making the Python ecosystem a truly first class experience under Windows. Virtual environments, poetry, and even tools for installing and managing command line scripts that integrate with the shell like pipx work just great under Powershell on Windows.

And if by chance you're coding something up that's native UNIX to its very core, Windows *still has you covered. Cue the Windows Subsystem for Linux!

WSL - I See Penguins!

With the avent of WSL2 and most recently WSL-g you really do have everything you need to seamlessly build, debug and run Linux programs on Windows, including those that require X/Wayland GUI support or sound.

It's not just some kind of compatibility shim, it's an actual Linux kernel running in Windows. The integration is so complete these days that you can run things like Docker within WSL successfully. That's a really big deal!

Also, most of the popular mainstream development tools like Pycharm and Visual Studio Code have superlative support for deploying to and debugging in WSL built in.

The amount and quality of work Microsoft has put into this is truly impressive. And unlike the Mac, you're not actually using some oddball FreeBSD user space running atop the Mach microkernel, you're running 100% Linux. It's turtles all the way down.

I Go Where The Innovation Is & Use What Works

As a technologist, I'm proud of the success I've had in sniffing out pockets of high velocity, high value innovation in the technology landscape.

Years ago, I was running Linux when many people were either using DOS, pre OSX MacOS or super expensive prorietary vendor workstations like Sun's Sparc. Being able to have an honest to god UNIX environment on commodity hardware was like Prometheus's gift of fire to the mortals. It really was that big a deal.

I still think the Linux desktop has incredible potential, but for me the obstacles imposed by my disabilities and the lack of accessibility features can be a real buzz and productivity killer.

So here I am embracing a desktop that works, with an ecosystem that works and a rather large well heeled company pouring resources into bar raising and innovation.

I look forward to exploring and leveraging the incredible potential this platform represents. Stay tuned for more posts as I go!

Plus ça change, plus c'est la même chose

I was recently in an online discussion about whether or not technologists should use "managed services" like the one I work for.

One gent essentially claimed that the move towards cloud and managed services represented an end game for our industry, and that we'd automate ourselves out of a job. This is what I said:

Will there be job reductions and resultant economic pain as a result of the move away from the data center and towards more cloud/managed services? Hell yes there will be!

Those who want to work in this business will find ways to adapt and continue to add value.

I’ve been working in technology for about 32 years. This doesn’t make me magical or omniscient or even smart but what it does make me is a witness to several waves of seismic change.

I came into the job market in the early 90s when DEC was imploding, PCs were ascendant, and the large expensive workstations vendors were dead companies walking but didn’t realize it yet.

Everyone thought the world would end and we’d all be out of work too.

Will it be hard? Yes. Will there be a lot of people who can’t or don’t want to adapt and will be left behind? Undoubtedly. Is that bad? Yes. However it’s the way our industry works and has since its inception.

We are all turning the crank that drives the flywheel of increased automation, whether we administer our own database clusters or not. The move to managed and cloud definitely represents a notable pinch point, and we’ll see how painful the transition will be, but it’s one paradigm shift in an industry that creates paradigm shifts for a living.

I’ve actually thought for a while that in the longer term, as compute at scale becomes quite a bit smaller and even cheaper, we could see a move back away from cloud because when you can host your company’s compute cluster in a cube the size of a printer and we have algorithms that can encode and enact services at scale in an operationally safe way, the value cloud adds will dwindle.

I love my job, and I love this industry, and plan to continue playing in this pool until I die, whether someone’s willing to pay me for it or not.

I assert that the constant negativity many of us exhibit is neither necessary nor desirable and represents a kind of immaturity that we will eventually grow out of as our industry continues to mainstream.

We’ll see.

The Eternal Novice Trap


It was the dawn of a new century in the tech world. We'd just survived the great Y2K scare which, for many of us, turned out to be nothing. I spent a memorably pleasant Y2K eve playing board games and sipping champagne at my company's East Cambridge office, enjoying the company of my co-workers. I felt like I was on top of the world.

Right around that time I encountered a book that would change the way I thought about computing. It contained a huge amount of overall incredibly positive and helpful advice. That book was The Pragmatic Programmer.

The Trap is Set

This book contains innumerable bits of incredibly useful advice. The pearls contained within its pages will help you build a successful career as a technology professional.

But I write this in the hope that you won't misinterpret one particular bit of advice like I unintentionally did. In some ways it hurt my career. Thankfully I became aware of it a few years back and am now headed in the right direction.

Here's the advice I used to hamstring myself:

Learn at least one new language every year. Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut.

The Pragmatic Programmer, 2nd edition

This is superb advice for its time, when the majority of programmers spent their days coding away in a single language or two.

It's superb advice to this day for that kind of person. If you've spent years coding in Python, why not try your hand at something with a radically different paradigm? By doing so you'll learn new ways of solving problems.

But zooming back to post Y2K me, that picture didn't fit me at all. I'd started out as a sysadmin, learning a huge amount about the care and feeding of UNIX based systems. I'd done some simple scripting to automate administrative tasks, but nothing at all complex or strenuous. A little bit of shell, some Perl, and I had things humming along just great.

Only I took the advice literally, despite my total lack of mastery of any programming language. With wild abandon, I threw myself into every new programming language I encountered..

The Bright, Shiny, Infinite Rabbit Hole

I played with countless languages, FORTH, a myriad of LISPs. You name it, I played with it. If there was a new hot language on the scene you can bet I'd be downloading it and figuring out how to write Hello, World and a few other toy examples.

But that's as far as it went, because, if I'm honest with myself, playing with new toys doesn't feel like work. It's a shot of dopamine. It feels really good in the moment. You feel accomplished because now you can talk about $LANGUAGE along with the rest of the cool kids who are exploring it.

There are also external reinforcements for this behavior. By being able to talk the talk, you can appear smarter than you are. You can probably even answer surface level questions in job interviews which can, in the short term, help your career.

But not unlike living on sugar and caffeine, that short term buzz will wear off, leaving you feeling empty and, ultimately, like the emperor walking around with no clothes. You can talk the talk like a champ, and be up with the latest buzz, but in some corner of your mind you may recognize that your basic skills are fundamentally lacking.

Brush Your Teeth, Eat Your Veggies, Get Sleep & Exercise

Thankfully, the fix is at least conceptually easy. Just stop doing that :) Pick a language that will become your daily driver, and focus on building your core skills using that language.

Build deep, featureful applications. Learn and exercise your skills using the full breadth of your language's ecosystem, and solve real problems using your language of choice.

For me, that language is Python. That's an easy choice because my day job is building infrastructure for a major cloud vendor and 90%+ of our tooling is written in Python. For the last few years I've promised myself to not learn any new programming languages until I become at least a Journeyman with Python.

You may find, as I did, that this is easier in concept than in practice. You may need some structure to help you achieve this goal. Everyone is different, so this isn't a one size fits all suggestion. I'll share some resources that may help.

Resources to Help Sharpen Your Tools

These days there is an embarrassment of riches out there, free for the taking to anyone with a computer and an internet connection to leverage. I'm just going to cover a few that I've found particularly helpful.

100 Days of Code with Python

If you're like me, having a free form set of exercises can be good, but adding some structure with definite time constraints and deadlines, even if you set them yourself, can be immensely helpful. This course was pretty much ideal for my needs. The idea is that you commit code every day for 100 days. This course uses that framework to take you on a guided smorgasbord tour of the incredibly rich Python ecosystem. The course introduces a particular topic or module and then has you build an interesting near real world application with it. I learned so much from this course that it alone has been a real boost to my career.

Completing a course like this can be a daunting task, especially while working full time. However I found the results are well worth the effort. Hopefully you can find something similar for your language of choice.


Exercism is an incredible resource regardless of the programming language you work in. It's not just a set of practice exercises, but a community of people who'll help review your code and provide mentorship.

Project Euler

These are language agnostic problem sets that will stretch your skills and force you to really exercise your problem solving skills. I myself have only scratched the surface with these, and plan to delve deeper in the future.

Parting Thoughts

I hope you'll find value in what I wrote here. I wish I'd had this article earlier on in my career. Maybe I can help someone avoid falling into the trap I did. To sum up:

  • Do learn new programming languages and paradigms, but learn them from a place of confidence and mastery with your primary tool of choice.

  • Don't fall for the trap of perpetually chasing after the bright shiny thing that's hot right now. Recognize that what's new isn't necessarily better. Take what will meaningfully help you advance your career and let the rest flow by. There'll always be more tomorrow.

  • Do keep having fun! You'll learn more quickly and retain more if you're finding enjoyment in what you do. Sometimes it means looking at things a little differently, but often that open mindedness can pay off.