DECEMBER 7, 2021

Beginner feeling

Every process needs persistence to yield long-term results.

Here are a few tips I try to live by to run away from the beginner feeling.

Make periodicity your friend.

Engage in your craft daily.

(If you can't, try to show up on a weekly or biweekly basis.)

But again, make periodicity your friend.

Otherwise, you'll repeatedly feel like a beginner.

You'll find yourself getting back at your practice, over and over again.

Show up daily instead to minimize that friction.


If you are wondering where the image files of your Apple Desktop backgrounds are, you can simply navigate to the following folder.

/System/Library/Desktop Pictures

To get to this folder, in case you don't want to remember the path, you can also do this.

  • Right-click on the Desktop
  • Change Desktop Background
  • Double-click on "Desktop Pictures"

To navigate to the folder with Terminal.

open "/System/Library/Desktop Pictures"

To navigate to the folder with Finder.

  • Menu bar › GoGo to Folder..
  • /System/Library/Desktop Pictures
  • Go

DECEMBER 2, 2021

SageMaker can be quite confusing. Here are some notes I took while learning how the model and output parameters work.

  • model_dir is provided as an Estimator function parameter.
  • output_dir and output_data_dir are provided as Estimator hyperparameters.

(See how to provide these arguments in code below.)

After a successful run, whatever is saved to each of these directories will be uploaded to a specific S3 location within your job's folder and bucket.

  • model.tar.gz will contain files saved to /opt/ml/model
  • output.tar.gz will contain files saved to /opt/ml/output and (inside of the data subfolder) the files saved to /opt/ml/output/data

Here's the sample directory tree with a entry point that saves a text file to each of these locations.

# Files saved to /opt/ml/model/

# Files saved to /opt/ml/output/
    # Files saved to /opt/ml/output/data/

# Files in the Estimator's source_dir
        # All files in your source_dir

Here's how you'd override these locations in your Estimator.

# Create a TensorFlow Estimator
estimator = sagemaker.tensorflow.estimator.TensorFlow(
        'output_data_dir': '/opt/ml/output/data/',
        'output_dir': '/opt/ml/output/',

And here's how you'd read their values inside of your entry point, e.g., Note that, even if you don't pass these three variables to your Estimator and its hyperparameters, you can capture them in your entry point script by defaulting to the SageMaker environment variables, namely, SM_MODEL_DIR, SM_OUTPUT_DIR, and SM_OUTPUT_DATA_DIR, which default to /opt/ml/model, /opt/ml/output, and /opt/ml/output/data.

import argparse
import os

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--model_dir", type=str,
                                       help="Directory to save model files.")
    parser.add_argument("--output_dir", type=str,
                                       help="Directory to save output artifacts.")
    parser.add_argument("--output_data_dir", type=str,
                                       help="Directory to save output data artifacts.")

    opt = parser.parse_args()
    print(f'model_dir › {opt.model_dir}')
    print(f'output_dir › {opt.output_dir}')
    print(f'output_data_dir › {opt.output_data_dir}')

Testing this functionality, I saved a text file to each of these locations to see what the SageMaker SDK was uploading to S3. (The resulting directory structure can be seen above.)

# Save a text file to model_dir
f = open(os.path.join(opt.model_dir, 'model.txt'), 'w')
f.write('Contents of model.txt!')

# Save a text file to output_dir
f = open(os.path.join(opt.output_dir, 'output.txt'), 'w')
f.write('Contents of output.txt!')

# Save a text file to output_data_dir
f = open(os.path.join(opt.output_data_dir, 'output_data.txt'), 'w')
f.write('Contents of output_data.txt!')

What's the difference between output_dir and output_data_dir?

SageMaker provides two different folders, the parent output folder and the output data subfolder. According to official AWS GitHub samples, output_dir is the directory where training success/failure indications will be written—which is an empty file named either success or failure—, output_data_dir is reserved to save non-model artifacts, such as diagrams, TensorBoard logs, or any other artifacts you want to generate during the training process.

I hope the read was helpful!

NOVEMBER 30, 2021

Play next

Instant gratification platforms—Instagram, Facebook, Twitter, Email—get us hooked to the constant consumption of new information and notifications, and on-demand media platforms—YouTube, Spotify, Netflix—teach us to skip ahead when content ceases to entertain us. As we give in to these impulses, we become less and less capable to avoid the urge to context-switch (or may I say content-switch) leaving what we were doing half done, engaging in yet another activity, and getting used to never completing anything. This phenomenon is what makes twenty to fifty-minute-chapter mini-series thrive. We consume things in chunks and don't want to commit to the two-hour movie anymore. But we eagerly play next when a show gets us hooked and binge-watch for hours. I'm in control. You think. But are you?

NOVEMBER 29, 2021

One Year of Live Streams — Teaching & Coding

Hi Friends—

We hosted two live events on YouTube to record a two-part podcast celebrating one year of live streams. The second part, out now, features a conversation with Jose Luis García del Castillo on teaching and coding live.

We talk about friction and automation, community, practice, content creation, and how the podcast and the live streams have evolved.

Special thanks to the community and to everyone who joined us live. ❤️

Listen to "One Year of Live Streams — Teaching & Coding"

NOVEMBER 27, 2021

Hold the icon in the macOS menu bar for two seconds.

NOVEMBER 23, 2021

Bitcoin, bookmaking, and publication announcements

This week, I want to share a few links and announcements.

Anthony Pompliano says denominating your assets in bitcoin is better than doing it in US dollars, as the inflation rate of the cryptocurrency is much lower than the majority of currencies commonly used to denominate assets. I haven't yet dived deeply into the world of non-fungible tokens (NFTs) and smart contracts.

I enjoyed watching Craig Mod's bookmaking video in Japan, which shows the craftspeople involved in the production process of his third edition of Kissa by Kissa.

I'm working on a new interview with an old friend—Jordan Gray—on friction and creativity.

I'm building a sound studio to record my podcasts and live streams, and I'll hopefully be commenting on the results soon; it involves a green chroma, acoustic panels, and recording gear.

Last but not least, I'm going to start publishing on Substack soon. You can subscribe here.

See you next week!

NOVEMBER 18, 2021

I found this approach to install unzip on SageMaker Studio with yum in the Terminal.

sudo yum install -y unzip

Now you can use unzip --version to verify unzip is installed, and unzip to extract the contents of a compressed file.

An alternative approach which didn't work for me

Run the following command (note the bang!) inside of a Jupyter notebook or Python console in SageMaker Studio to install unzip.

!conda install -y -c conda-forge unzip

After running that command, I don't seem to be able to run unzip in Terminal yet.

NOVEMBER 16, 2021

It's getting cold(er)

The end of the year is coming closer, and it's getting cold(er) here in the South of Spain. (My friends from Massachusetts laugh when they hear me say it's cold; they have to shovel the snow from their yard.) Summer clothes in. Winter clothes out. Here, in Málaga, it's sunny outside. You can walk on a sweatshirt.

We went away with friends to the countryside of Córdoba to disconnect over the weekend; walks, barbecue, and fireplace. I often wonder how we'd disconnect from work if there were no weekends, and constantly remind myself of a passage from Cal Newport's Digital Minimalism, which says the key to thriving in our high-tech world is to spend much less time using technology. Even though I try, I haven't found the right way to do it.

NOVEMBER 12, 2021

According to a forum post by a verified Adobe contributor, AI Robin is a background process, introduced in Illustrator 2020, responsible for background save and export tasks. I got warned by Lulu, an app that prompts for verification to enable any outgoing connections. On Windows, the same process is called AiRobin.exe. Apparently, users report AIRobin hogging huge amounts of RAM and slowing down the machine at times.

NOVEMBER 9, 2021

Using friction to break bad habits

Last week, I wrote about identifying where the friction lies to avoid it as much as possible. Arguably, that would lead us to ship more work and focus on the essentials. But there's a specific situation in which friction becomes our friend: when we try to break bad habits.

I learned about this idea from James Clear's 2018 book Atomic Habits. "The best way to break a bad habit is to make it impractical to do. Increase the friction until you don't even have the option to act."

Instead of working against friction, we engineer ways to produce more of it.

In his book, Clear provides a practical example. "The brilliance of the cash register was that it automated ethical behavior by making stealing practically impossible. Rather than trying to change the employees, it made the preferred behavior automatic."

Another example is to avoid distractions by logging out from email, social media, and services that steal your time. Having to log back in each time you visit them makes the experience less enjoyable and serves as a wall to potential distractions.

By making what you want to avoid harder, friction helps break bad habits.


As is port 3000, port 5000 is commonly used to serve local development servers. When updating to the latest macOS operating system, I noticed my React development server, which I'm serving with React create-serve was using a port other than 5000, because it was already in use. (You may find a message along the lines of Port 5000 already in use.)

By running lsof -i :5000, I found out the process using the port was named ControlCenter, which is a native macOS application. If this is happening to you, even if you use brute force (and kill) the application, it will restart itself. In my laptop, lsof -i :5000 returns that Control Center is being used by process id 433. I could do killall -p 433, but macOS keeps restarting the process.

The process running on this port turns out to be an AirPlay server. You can deactivate it in System Preferences › Sharing, and unchecking AirPlay Receiver to release port 5000.

NOVEMBER 5, 2021

The Visual Studio Code (VSCode) development team has been working hard to ship, a version of Visual Studio Code that runs entirely in your browser.

NOVEMBER 2, 2021

Where's the friction?

Every piece of work can be considered either required—has to be done—or unnecessary—could be skipped but somehow slipped into your to-do list.

The first step to avoid friction is to say no to the unnecessary.

Once we've filtered out work what isn't required, we categorize the remaining tasks into core or delegable.

Core work is crucial for you to do. Delegable work can be automated or delegated and carried out, without your intervention, by a machine or human, potentially faster and better than yourself.

The second step to avoid friction is to delegate as much as you can without sacrificing the quality of your work, running away from perfection, and focusing on what's essential for you to work on.

Friction is on what doesn't need to be done and what could be done by someone else.

OCTOBER 26, 2021

One Year of Live Streams — Live Q&A

Hi Friends—

We hosted two live events on YouTube to record a two-part podcast celebrating one year of live streams. The first part, out today, features audience questions on the challenges and evolution of the channel after a year of streaming (almost) weekly.

I mentioned way too many things in this episode, so I tried my best at linking to most terms and technologies in the notes below.

Listen to "One Year of Live Streams — Live Q&A"

OCTOBER 26, 2021

Ding! Ding!

Ding! Ding!

A dummy notification drags you out of the meeting.


You look back at your computer screen.

But a tiny distraction was enough to lose track of the conversation.

Could you repeat the question?

OCTOBER 19, 2021

Digital art, black boxes, live streaming, and more

Hi, there! Today I want to share a few things that went live recently.

On the podcast.

I released a new episode with Aziz Barbar on non-fungible tokens (NFTs), blockchain, cryptocurrencies, and digital art. You can listen here.

I know very little about the fast-moving world of digital currencies and the new age of digital art, and these byte-sized episodes are an attempt for us to catch up with the latest developments. I intend to publish essays on the topic to share my findings.

While everyone's wondering whether the representation of ownership of digital creations with tokens is a bubble, events such as the 69-million dollar sale of Mike Winkelmann's body of work—@beeple_crap—in an auction by Christie's significantly contribute to the validation of this piece of technology.

A future episode with Aziz will discuss the role of black-box algorithms in our culture.

On the live stream.

Last week, I hosted two live events on YouTube to record a two-part podcast celebrating One Year of Live Streams, to be released soon. The first part features audience questions regarding the evolution of the live stream after a year of weekly streams. The second is a follow-up conversation with Jose Luis Garcia del Castillo on our experience coding live.


Lastly, Jose Luis invited Andrew Heumann to his Introduction to Computational Design class (GSD-6638) at the Harvard GSD to give a guest lecture on Architectural Automation & Augmentation. You can watch here.

OCTOBER 18, 2021

I found the following error while trying to execute PORT=4444 node ./bin/server.js on my Node.js application.

SyntaxError: Cannot use import statement outside a module

I solved it by adding the following into the package.json file of my NPM project.

  "type": "module",

OCTOBER 16, 2021

Bytes — NFTs and Digital Art

Hi Friends—

It's hard to keep up with the fast-moving world of digital currencies and the new age of digital art.

In this new episode of Bytes, Aziz and I talk about non-fungible tokens (NFTs), blockchain, cryptocurrencies, and digital art.

Listen to "Bytes — NFTs and Digital Art"

OCTOBER 12, 2021

Machine Learning-Based Audio Editing, React, UI Libraries, NFTs, and COVID

Hi Friends—

Today, I bring you an informal chat with Nate Peters, a friend and former guest of the show—a conversation on the machine learning-based audio-editing solution this podcast is being produced with, web components, React and UI libraries, the effects of COVID-19 in our work lives, NFTs and cryptocurrencies, and the new informal catch-up conversation podcast format we're testing out.

We were screen-sharing during part of this conversation and no recording is available. But we've compiled a detailed list of episode notes, and the YouTube video includes a full transcript as closed captions.

Listen to "Machine Learning-Based Audio Editing, React, UI Libraries, NFTs, and COVID"

OCTOBER 12, 2021

Will new tools make your content any better?

All you need to start a podcast or a YouTube channel is entry-point equipment to begin recording and releasing content. Buying a new microphone (e.g., Audio-Technica ATR2100x), vlogging camera (e.g., Sony ZV-E10), or camera mount (e.g., Elgato Mount) won't make the content any better. Better sound, video quality, and production value? Sure. But not much more than that. You'll still need to create and edit content.

I produce a lot of material. Yet, I feel the need to create with more structure, plan, define a clear agenda, establish publishing protocols, develop editing and post-processing workflows, collaborate with other professionals, and put more time into editorial content creation.

I need to filter, select, write, research, and have a clear idea about what I want to talk about, teach, discuss, and the questions I want to cover—to fight the resistance, stop complaining and hiding behind the process, and focus on the content.

That—and not new gadgets—is what will make my content more valuable, more listened to, watched, read, and, most importantly, beneficial to my audience. In turn, people may come back for more and get something meaningful.

I want to share what's on my mind, learn, and teach my learnings through a consistent message and a constant publication flow. After all, that's the type of content I like to consume.

OCTOBER 5, 2021

A tiny notepad as checklist

I've tried dozens of ways to track my to-dos, including Dropbox Paper, iPhone Reminders, Clear for iOS, Trello, and a long etcetera. None of them seem to work for me in the long run. I'm too good at cramming my lists with items.

With so many items, Kanban boards1 are hard to navigate2 and I forget to check to-do apps, and things end up slipping by my workday.

My latest attempt is a simple running list in a tiny notebook on the table.

I write down the tasks I want to complete today (maybe tomorrow) and strike through individual action items as I do them. When I finish the majority of to-dos in the list, I scrap the page and transfer the remaining to-dos to the next page.

At the moment, I'm using a 10-by-9-centimeter notepad in the shape of a chocolate bar, and want to try MUJI's tick box tape, which turns any sheet into a checklist.

How do you track your to-dos?

  1. "A kanban board is an agile project management tool designed to help visualize work, limit work-in-progress, and maximize efficiency (or flow)." Atlassian

  2. Even though my boards end up having way too many cards, I'm a happy Notion user. I can create Kanban boards and visualize their data with multiple view types and filters, which converts my board into a database I can browse in many different ways. However, I still prefer writing down urgent items outside of this board to ensure they don't slip by. 

SEPTEMBER 28, 2021

There's no post today

Paradoxically, announcing there's no post today means there's a post.

My commitment is to publish a sketch and story every Tuesday, both in English and Spanish. And it isn't easy. I find joy when I schedule my weekly publications in advance, and I often fantasize that I'll put the hours needed to prepare posts weeks, maybe months, ahead of time. But that rarely happens. I was close to doing that for August, looking to unplug from the screen during my vacation. Yet, I ended having to do some writing, translating, and Photoshoping amongst the hot days of Summer.

Here's a personal note I wrote on the morning of July 7, 2021.

Writing a good newsletter post with 466 words […] makes me feel good. It's Monday morning, and my post (in English and Spanish) is scheduled for tomorrow. It's 9:40 AM, and I need to keep going, making progress in other areas not to be caught empty-handed later on my day.

I realize how great it feels to finish to-dos early in the day, going on with your day without pressure. It's then when I think, I wish I did this more often! But, no matter how much structure I try to introduce into my daily routine, every day is different.

As you can see, I lied—I had the first line of this essay as a backup post in case I had to miss a publication, but it ended up sparking a reflection that I decided to share with you today.

SEPTEMBER 27, 2021

From MongoDB's JSON Schema Examples Tutorial page:

JSON Schema is an IETF standard providing a format for what JSON data is required for a given application and how to interact with it. Applying such standards for a JSON document lets you enforce consistency and data validity across similar JSON data.

The purpose of a JSON Schema is to define the allowed property names and data types allowed to facilitate the validation of a given JSON object. This reminds me of TypeScript definitions, where type-checking happens by default after you've instantiated a given interface or class.

SEPTEMBER 22, 2021

Work or Walk podcast

Hi Friends—

Today, I bring you a two-minute episode on reclaiming our time with the help of automation. It's an audio version of a short essay I published on July 21, 2020.

Listen to "Sketches — Work or Walk"

SEPTEMBER 21, 2021

If you're trying to remove a directory using the os.rmdir function, but it contains other files, you'll probably hit the following error.

OSError: [Errno 66] Directory not empty:

You can ignore this error by using the shutil library instead of os.

import shutil

Note that Python won't prompt you to confirm this deletion action and this may lead to deleting files by mistake.

SEPTEMBER 21, 2021

A set of informal rules

Conventions let us skip certain decisions making them automatic.

I adhere to a set of informal rules to determine why, how, and when I write or sketch. I do it daily to think, learn, teach, remember, and portray and share what I experience. And even though I experiment with different formats and gadgets now and then, I try to stick to the same typing and drawing medium to pay attention to the content I'm making, not the tools.

Defining what we do and our processes let us clarify why and how we do them. Sharing that reasoning with others allows them to understand your craft and practice.

SEPTEMBER 17, 2021

GoPro just introduced the new HERO10, a camera that can record 5.3K video at 60 fps and 4K at 120 fps. Frame grabs are 19.6 megapixels and photo captures are 23 megapixels. The device features HyperSmooth 4.0 stabilization, which gets rid of shaking altogether, making the recording experience more relaxed. The slogan for this year's release is Speed with Ease. They keep making the user experience more intuitive and the inner workings of the GoPro faster. Like previous models, the HERO10 lets you live stream at 1080p, a feature I haven't tested yet. I can't wait to try one of these out while freediving.

SEPTEMBER 16, 2021

When trying to stitch several videos together with FFmpeg with the following command.

ffmpeg -f concat -i list.txt -c:v copy concat.mp4

I came across this error.

[concat @ 0x7fca4281b800] Unsafe file name '2021-09-16'
list.txt: Operation not permitted

The issue, which I've been able to fix manually other times, is that there's an unsafe character one or more input video names, the space.

As it turns out, we only need to turn off this safety measure for FFmpeg to skip this check, passing the -safe 0 flag in our command.

ffmpeg -f concat -safe 0 -i list.txt -c:v copy concat.mp4

Hope that helps!

SEPTEMBER 15, 2021

iPhone 13

Yesterday, Apple released the iPhone 13, iPhone 13 mini, iPhone 13 Pro, and iPhone 13 Pro Max. The new Cinematic Mode looks promising, even though it's limited to 1080p at 30 fps—it can autofocus subjects as they come into a scene and unfocus when they look away, plus you can adjust which subject to focus on real-time and change the focus at any moment in your footage after recording. (These selections aren't baked into the video but digitally generated.) It's great to see the storage capacities starting at 128GB and going up to 1TB on the high-end model.

The iPhone 13 mini will probably be the one to replace my iPhone 6. The mini is slightly smaller than the iPhone 6, yet its screen (5.4-inch) is larger than the one on the 6 (4.7-inch). I can't imagine carrying a Pro Max daily.

Want to see older publications? Visit the archive.

Listen to Getting Simple .