Saturday, October 24, 2020

The inheritance of closed-mindedness

"Is this closed-mindedness something we want to pass along to future generations?"

 - Martin Scorsese, 1993

This provocative question was posed by Martin Scorsese as part of a response to a criticism of famed filmmaker Federico Fellini.

What struck me about it is it's timelessness.


Has there ever been a time in history when it wasn't relevant?


I think the timelessness of this questions speaks to human nature.

Just as the challenge to understand one another is intrinsic, the need to strive for that understanding is equally so.


Sunday, September 6, 2020

You reap what you sow: Lottery and lightening

"You reap what you sow"

My mom loves quotes. Growing up, I heard this one a lot.

It always came after someone's downfall, as if they should've known better. As if the universe is governed by this simple phrase and life can be mastered by living within its bounds.


But, then, why doesn't life ever seem to go the way it's supposed to?


Consequences, good and bad

We all learn that talking behind someone's back leads to conflict.

We all learn that practicing leads to better performance.

In other words, the actions we take today produce the consequences we experience tomorrow.


But, I still didn't pass the job interview I spent hours and hours preparing for. The one I have over 10 years of highly relevant experience for.

And while I was failing my interview, the guy who was out partying when I was studying, the guy who was spending lavishly while I saved money for retirement.. that guy just made a million dollars trading options in the stock market.


Why isn't the universe operating like it's supposed to?


Why am I such a loser that even the universe bends its rules to show me how worthless I am?


There's fundamental truth in the statement that our actions have consequences. It's easy to understand. It's easy to observe.

It gives us an easy way to make sense of the things we experience.


And it makes it easy to overlook a harmful consequence of internalizing this framework.


If we see everything as a result of our actions, it becomes reeeally easy to blame ourselves for anything and everything that happens to us.

That interview I didn't pass? I should have studied hard. Oh, I did study hard? Well.. I don't know. I guess I'm just stupid.


If we see everything as a result of our actions, it's easy to miss the fuller picture and all the variables at play. It's easy to overlook and under-appreciate how much is outside our control.


Want to win the lottery?

Have you ever dreamed of winning the lottery?

Sure you have.. a song like Billionaire doesn't go 4-times platinum without a lot of people resonating with it's hook, "I wanna be a billionaire, so fucking bad".


Either way, the universe doesn't care.


We both know no one wins the lottery through sheer force of desire, no matter how much they want it.


The trick to wining the lottery's simple: Buy a ticket

The single pre-requisite for winning the lottery is buying a lottery ticket.


Here's a fun fact Your chance of winning the lottery is 1 in 14 million.


The trick to getting struck by lightening's simple: Stand outside in a thunderstorm


Here's another fun fact: Your chance of being struck by lightening in any given year is 1 in 500 thousand.


Wining the lottery's a pretty positive consequence of buying a lottery ticket.

Getting struck by lightening's a pretty horrible consequence of standing outside during a thunderstorm.


In both situations, we have some control over the thing we do or don't want to happen. But, we have very little control over it.


Sometimes, shit happens

The point of all this is that sometimes, shitty things happen to us. A lot of shitty things've happened to me, and I'm sure a lot of shitty things've happened to you.

I've also been fortunate enough to have had a lot of good things happen to me too.


These days, I'm less inclined towards attributing everything that happens in my life to my actions. I'm more inclined towards doing what I can to make good things happen, and recognizing how much outside my control contributes to all things that happen.


Takeaway: It's not your fault, but it is your responsibility

It's unhealthy to blame to ourselves (or to accept blame from others!) when things outside our control lead bad things happening.

It's healthy to accept responsibility for acting on things within our control to make good things happen.


Easy to say, difficult to internalize.


But, I'm optimistic that it can happen with practice, and practicing is something within my control. ;)


--

Genevieve, thank you for reading a draft of this and discussing the topic with me in so much depth!


Friday, August 14, 2020

Dynamically loading modules in Python 3

Being able to programatically load python files as modules is a pretty cool capability of Python.

I'll jump to the punch, then step back to fill in context.

First, here's the file that dynamically loads peer python files as modules:

# File: dynamically_loaded_modules/__init__.py

import glob
import importlib.util
import sys

from os import path


def _get_module_name_from_file_path(file_path, module_name_prefix=''):
    if not file_path.endswith('.py'):
        raise ValueError(f"File doesn't have a '.py' extension: {file_path}")

    file_name = path.basename(file_path)
    file_name_without_ext = file_name[:-3]

    if module_name_prefix and not module_name_prefix.endswith('.'):
      module_name_prefix += '.'
    return module_name_prefix + file_name_without_ext


def load_modules(registry):
    path_string = path.join(path.dirname(__file__), '*.py')
    module_paths = [
        file_name for file_name in glob.glob(path_string)
        if not file_name.endswith('__init__.py')
    ]

    for module_path in module_paths:
        module_name = _get_module_name_from_file_path(module_path)

        if module_name not in sys.modules:
            module_spec = importlib.util.spec_from_file_location(module_name, module_path)
            sys.modules[module_name] = importlib.util.module_from_spec(module_spec)
            module_spec.loader.exec_module(sys.modules[module_name])

        module = sys.modules[module_name]
        if not hasattr(module, 'load_module') or not callable(module.load_module):
            raise Exception(f'Auto-load module {module} is missing required function "load_module"')

        module.load_module(registry)


Next, here's an example of a peer python file that gets dynamically loaded as a module:

# File: dynamically_loaded_modules/example.py

def load_module(registry):
    registry.register(f'{__file__} was dynamically loaded!')


Finally, here's example usage:

#!/usr/bin/env python

# File: app.py

from dynamically_loaded_modules import load_modules


class Registry:
    def __init__(self):
        self._registrations = []

    def register(self, description):
        self._registrations.append(description)

    @property
    def registrations(self):
        return self._registrations


registry = Registry()
load_modules(registry)
print(registry.registrations)


The use case I had for this was dynamically registering API routes for a flask app.

This solution offers the conenvince of registering new API routes via Flask's route. That's achieved by (1) passing the Flask app to load_modules and (2) calling flask_app.route in each dynamically loaded file's load_module function.

Actually, I take back what I said earlier. I'm not going to fill in too much context right now. Otherwise, I'd never publish this. :)

Instead, I'll try to come back later and update this post to break down the code more.

Thursday, February 6, 2020

How to Run an Old Version of macOS After Upgrading to Catalina

I have a MacBook Pro, which I'm usually happy with.

However, I recently wanted to play a game that's only available on Windows. So, I went about figuring out how to run Windows software on a Mac.

After some initial investigation, I had the following options:
  1. Run Windows in a virtual machine using software like VirtualBox or Parallels
  2. Install and run Windows on my laptop using Apple's Boot Camp
  3. Use a virtual Windows desktop using a product like Amazon WorkSpaces
  4. Use a compatibility layer to run the Windows application on my laptop without a Windows install using Wine or Crossover
I decided to dig deeper into using Wine because I didn't want to buy a Windows license or make recurring payments to Amazon.

Unfortunately, macOS Catalina (which is what I have) doesn't support 32-bit applications and the game I wanted to play requires 32-bit support. So, to run the game using Wine, I'd need to use an older version of macOS.

I wasn't willing to downgrade my OS for this, so I started looking into how to run multiple version of macOS on my laptop. Here's what I found:

Overview


To run a different version of macOS on the same laptop, we'll:
  1. Create a disk partition to hold a "bootable installer"
  2. Create a bootable installer for the older macOS version on that partition
  3. Create a disk volume to install the OS on
  4. Install the OS on that volume
WARNING: Creating, modifying, and erasing partitions can have serious consequences. You're at your own risk if you decide to attempt this.

Step 1: Create a disk partition


To create a bootable installer, we need somewhere to put it. A good option is a thumb drive. I didn't have one on hand, so I created a disk partition on my mac.

Basically, I followed Apple's instructions the instructions for creating a physical disk partition. The following are important:
  1. About 8GB of capacity is needed
  2. The partition must be formatted as "Mac OS Extended"
Here's how I set up my partition:
  1. Open Disk Utility and select "Show All Devices".
  2. Select the physical hard drive in the left panel and click the "Partition" button on the top.
  3. Select an existing partition in the pie chart, from which the new partition will be created (the existing partition will "donate" disk space for the new partition). Then, click the "+" button.
  4. Give your partition a name (the name is arbitrary - just use something you'll remember), select "Mac OS Extended (Journaled)" as the format, and set the size to 10 GB.
  5. Click "Apply" and be patient while the new partition is created.

Step 2: Create a bootable installer


For this step, I followed Apple's instructions for creating a bootable installer.

For me, this involved:
  1. Download macOS Mojave.
  2. Quit the installer (it started automatically after download, but we need to run it from the command line).
  3. Open a Terminal window.
  4. Run createinstallmedia on the new disk partition created in step 1:
    sudo /Applications/Install\ macOS\ Mojave.app/Contents/Resources/createinstallmedia --volume /Volumes/Bootable\ Install\ Partition.
    Note that your paths might differ. The second one depends on what you named your partition.
  5. Follow the prompts. Note that after this completes, the partition is renamed to something like "Install macOS Mojave".

Step 3: Create a new volume


We need to create a new volume on which to install the OS.
  1. Open Disk Utility again.
  2. Select the volume where macOS Catalina is installed. For me, this is "Macintosh HD".
  3. Click the "+" above "Volume" at the top.
  4. Enter a name for the new volume (I used "Mac OS Mojave"), leave the format as APFS, and click "Add".
  5. Wait while your new volume is created.

Step 4: Install the OS


Now, we just use the bootable installer from step 2 to install the OS on the new volume from step 3.
  1. Restart the laptop while holding down the option key. For additional guidance, see the "Use Startup Manager" section of Apple's guide for selecting a different startup disk.
  2. Once the laptop restarts, select disk with the bootable installer. For me, it was the one named "Install macOS Mojave".
  3. Begin installation by selecting Install macOS.
  4. Go through the install process. When prompted to select a partition to install the OS on, select the one created in step 3.

Wrap-up


That's it! After installation, your computer should startup in the OS you installed.

If you want to get back to your main OS installation, just follow the same procedure for using the startup manager (restart while holding the option key) and select it (for me, it's called "Macintosh HD").

So, after all this, I was able to run my Windows game on my Mac laptop by booting into the macOS Mojave install and using Wine.

All this so I could play a stupid game.. 😂🤦

I hope this helps with whatever you need it for!