Previous summaries: 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022.
I’ve continued to keep track of my reading using Goodreads. My profile has nearly the full list of the books I’ve read since 2010.
Last year I wrote:
I’d like to do a better job of keeping track of my reading. This should be pretty easy to do.
I don’t feel too bad about the reduction in reading but I’d like to read more this year. Some of my reading time has been replaced with worthwhile endeavors but not always.
Reading rejuvenates me. I need to keep it a regular part of my life.
Well, I don’t remember how poorly I did in 2022 of keeping tack of reading but I don’t think I did a great job in 2023. Was it better than 2022? Perhaps.
I didn’t write many reviews for specific books nor did I send out any emails about what I was reading throughout the year. But I did do fewer corrections of the data I had in Goodreads.
I did read more than I did last year.
If I were grading myself on how well I achieved my goal, I’d give myself a B.
Below are the highlights from 2023. Any title link will bring you to Goodreads.
I started off the year with this book and really enjoyed it. It is a pandemic story that has characters spanning hundreds of years.
It is a little weird and beautiful. It did an excellent job of conveying feeling.
This is one of the few books that I did a mini-review of when I finished it. That review:
A beautiful novel. While reading, I found myself rereading parts. Not because the sentences were confusing but because they expressed such a clear feeling.
I highly recommend this book.
This book is real weird and fantastic. The main character is extremely interesting. I had a blast reading this.
I really enjoy this series and thought this as an excellent addition to it.
This was an excellent book about friendship and creative, collaborative pursuits.
A friend offered to send copies of this books to anyone who was up to reading it and I’m glad I spoke up and asked. Each chapter presents a philosophy. And the next chapter usually presents a different, conflicting philosophy. Every chapter is small, so it is easy to read a bit and take some time to reflect.
A bunch of distilled ideas around improvement. No fluff, just tips.
I have mixed feelings about including this book on the list. I reread this series when I was debating watching the television show. Even on a second read, I still enjoyed this story.
Is it complex and view shattering science fiction? Nahh, not really.
Is it entertaining? Yep.
This is a really well done book that explores a modern gladiator system of punishment for criminals. It is dark and creative and a solid commentary on modern society.
Maybe this should have been five-stars.
I knew nothing about it going in and thought this was a interesting take on first contact with aliens.
I read 53 books in 2023.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
There are definitely some spiky months in the data.
Unsurprisingly, electronic books are still the dominate format.
1 2 3 4 5 6 |
|
Fiction continued to dominate the book count this year. If I did this by page count I think it would tell a different story, as I read quite a few short stories published as Kindle books and this skewed my fiction book count high.
1 2 3 4 5 |
|
Here is the star rating distribution.
1 2 3 4 |
|
I’d like to maintain a regular reading practice. I think this means having a similar number of pages read this year.
I have a massive stack of books at home that I haven’t read through yet, I’d like to whittle that down some.
]]>Previous years: 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021.
I’ve continued to keep track of my reading using Goodreads. My profile has nearly the full list of the books I’ve read since 2010.
This year I did a poor job of keeping Goodreads updated. I had somewhat stopped updating Goodreads, or at least caring if I did it accurately, because I thought they were killing the ability to export your data. Luckily, that feature hasn’t been removed so I’m going to continue using the service.
Last year I wrote:
I used to be pretty good at capturing some thoughts upon completion of a book. I haven’t been doing a great job of that. I’d like to do better this year.
We’ll see what that entails but it might take the form of having more discipline around sending out some thoughts in the newsletter.
I accomplished absolutely nothing related to the goals I wrote at the beginning of 2022.
I didn’t write down thoughts on books closer to when I finished them. I didn’t keep my Goodreads data updated. I didn’t send out updates to my newsletter.
Below are some highlights from 2022. The titles link to Goodreads.
I didn’t write many reviews on Goodreads this year and did not write detailed reviews in this article. I’d encourage you to click the links and read reviews on Goodreads.
I love George Saunders' writing and especially enjoy his short stories. This collection delivered.
A science fiction classic that deserves to be read.
Gist of the book: Life is short and you won’t be able to accomplish everything you desire.
I enjoyed reading this and would benefit from reading it (or at least the Goodread’s reviews) again. This review on Goodreads is excellent.
I found this book fascinating and it made me interested in breathing. It was a nice mix of self-experimentation and reporting on studies. The history of the shape of our faces and how it affects breathing really hooked me into this book.
I enjoyed the book enough that I also listened to a significant portion of it while on a road trip so my partner could also consume it.
This probably could have been rated five stars. It is a ridiculous and long novel that rewards the reader for paying attention.
Probably the highlights for me were the chapters from the perspective of a pet.
I thought a couple sections dragged a bit and are what held me back from five stars.
To say I like Murakami’s writing would be an understatement, so reading a collection of essays by him about his writing was a pleasure. I learned a bunch about Murakami and his journey to becoming an internationally renowned author. At least as presented by Murakami, aspects of his life seem as surreal as some of his books.
This didn’t earn five stars because I found myself just not caring about some of the topics. But overall, solid book, especially for someone that enjoys Murakami and enjoys reading about writing.
Octavia Butler is one of my favorite authors and I devoured the first three books in this series. I enjoyed the first book, Wild Seed, the best.
I didn’t realize until writing this up that there is a fourth book in the series and I’ve immediately queued up reading it.
Compared to my usual number of books and pages read, this was a low reading year. I read 35 books in 2022.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Here is a breakdown of books finished by month. There were even a couple months where I allegedly didn’t finish a single book, though I wonder if that is actually true or of it is a data issue.
Electronic books continue to be the dominant format. Audio book could be 0.5 for how much I listened to Breath while on a road trip.
1 2 3 4 5 6 |
|
Fiction dominated this year.
1 2 3 4 5 |
|
Here is the star rating distribution.
1 2 3 4 |
|
I’d like to do a better job of keeping track of my reading. This should be pretty easy to do.
I don’t feel too bad about the reduction in reading but I’d like to read more this year. Some of my reading time has been replaced with worthwhile endeavors but not always.
Reading rejuvenates me. I need to keep it a regular part of my life.
Have any book recommendations? Please shoot me an email or leave a comment.
]]>Some bookmarklets I use on my desktop browser include:
For years, I thought I was restricted to only using bookmarklets in my desktop web browser. I hadn’t effectively used mobile bookmarks before and thought that clicking them would be a huge pain.
It turns out, I was wrong! I recently learned that if you start typing a bookmark’s title into your mobile browser’s location bar, it will let you select the bookmark. This means you can easily execute a bookmarklet just by starting to type its name and clicking it when it appears. This “search for bookmark in location bar” technique works with at least Google Chrome and Brave running in Android.
Below are the two bookmarklets I use regularly on my phone. They exist to bypass paywalls.
This one prepends http://archive.is/
to the current URL:
1
|
|
This one changes theatlantic.com
to theatlantic.com.
(though it no longer gets around their paywall):
1
|
|
To get them onto my phone, I added them a bookmarks on my laptop’s Chrome and synced them to my mobile phone. Once in my mobile Chrome, I edited the bookmark in mobile Chrome, copied the code, and pasted it into a bookmark in Brave.
I type three characters into my mobile browser’s location bar before I can select either of these bookmarklets. That is quicker than editing the URLs by hand and has improved the experience of reading articles on my phone.
]]>Here are links to my previous end-of-year reflections: 2013, 2014, 2015, 2016, 2017, 2018, 2019, and 2020.
I’ve continued to keep track of my reading using Goodreads. My profile has nearly the full list of the books I’ve read since 2010. Here is my 2021.
Last year I wrote:
I have quite a few unread books sitting on my virtual and physical bookshelf. This feels like setting a really low-bar but this year I’d like to read some of these unread-but-owned books.
I’m also planning on reading at least one book on writing and one book on climbing. This goal is almost a subset of the above goal as I have books on both these topics sitting on my shelf.
Did I achieve those goals? No.
Looking through my list of read books, I think only one of those a book I owned at the beginning of 2021. I did not read some already owned books; I read a single already owned book.
I did read a book on writing, George Saunders' A Swim in a Pond in the Rain, and multiple climbing books, Rock Climbing Technique by John Kettle and Rock Climbing in Kentucky’s Red River Gorge by James Maples.
Early in 2020, at the request of some readers of this site, I started a mailing list. During 2020 I used this newsletter as a way to notify subscribers of new articles posted to this website and write up short blurbs on books I had finished. Except for a single email, I also didn’t send out any updates to the newsletter.
This is partially because I didn’t write many articles last year. I generally try to write about one article a month but I did not do that in 2021. We’ll see if I pick back up this habit in 2022.
Below are some highlights from 2021. The titles link to Goodreads.
I didn’t write many reviews on Goodreads this year and did not write detailed reviews in this article. I’d encourage you to click the links and read reviews on Goodreads.
This was my third time reading Dune. I read it in preparation for seeing the 2021 film.
I’m a huge fan of Dune but parts of it definitely haven’t aged well. I think the story manages to be complex and have plenty of movement but somehow isn’t overwhelming. I thought the film did a pretty good job of capturing that.
The first time I read Dune, I also made the very first Kindle Dune Dictionary. If you are reading on a Kindle and haven’t read the book before, I’d recommend purchasing the dictionary. I didn’t find it useful on my third time through the book but it made my first read through better.
In August and September, I pretty much devoured the entire Vorkosigan Saga. I read all these books pretty much back to back and can barely distinguish them.
I’d recommend the series. It was a fun series and there are quite a few books in it. For some reason, this book stood out and is the only one I gave five stars.
These are two incredible books. Arkady Martine built a great world. Politics, aliens, and poetry all show up in these books and it is great.
Go read some reviews (perhaps this and this) and then go start this series.
The book starts with what feels like a collection of short stories and grows into a story of struggle, triumph, and failure. I can’t point to what made this book stand out to me but a I really enjoyed it. It might have had some moments that dragged a bit but I still loved it.
I went into this book knowing nothing about it and found it beautiful. The writing is lyrical and the way the story is told worked really well.
The book isn’t that long and I absolutely devoured it.
This is a 35 page short story. Go spend the short time it takes to read it. And then go read the rest of Adichie’s writing.
This book is fantastic. Generally, the format of the book is that you read a short story and then read George Saunders' thoughts about that story.
This book slightly changed how I think about stories.
This is a relatively short, beautiful book. I experienced a full range of emotions while reading it.
A solid book on the benefits of rethinking your positions. A very short summary is that it is good to update your beliefs and be curious. There is little benefit to being wrong longer. Learn how to rejoice in correcting your beliefs and embrace updating your viewpoints.
There is a some overlap of concepts in this book and the book Moral Tribes. If you are also well-versed in cognitive biases, parts of this book will be a repeat.
I think a second edition came out immediately after I finished reading the first edition. Hopefully the second edition has high quality updates as the original edition of this book is pretty solid. I’ve lived the vision promoted by this book and it is a good place to be.
A short book full of specific drills that are intended to improve your skill in climbing. This book isn’t about improving your strength, flexibility, or endurance. It is all about getting better at movement and paying attention to your movement patterns.
I’ve taken some of these drills and incorporated them into my climbing practice. I plan on digging back into this book and incorporating more of them.
This book is a mix of the author’s personal experience, policy, and science and makes the argument that drugs should be legal. Probably worth reading if you have any sort of reaction to that last sentence.
Reading some reviews on Goodreads gives a fairly balanced view of what this book is about. Even if I personally gave this book five stars, I find myself agreeing with a wide range of reviews by others.
A couple other reviews (one, two) described this book as comforting science fiction. I think that is a great description.
The world feels cozy. It is full of generally nice folks going about their lives and interacting with each other over tea. This main character in this book is non-binary and you get to hang out with them as they live their life. It feels like a nice place to be with reasonable folks and respect between humans, nature, and robots.
It is a relaxing read that feels like a gentle fable that muses on life and what it means to exist.
This book has a very narrow audience. If you have heard about the Red River Gorge, rock climb, and are interested in the history of the area you should read this book.
I learned a lot about one of my favorite places to rock climb.
There is a really good chance I should have given this book five stars. It was great. This book tells the story of the Hildebrandt family through interweaving perspectives of the family’s members. The characters are complex and the perspectives are interesting. I hope Franzen can continue to deliver this level of story in the sequels.
This goodreads review does a great job of selling the book.
This book does a wonderful job of describing what makes a gathering great. It was a bit hopeful to read this book early in 2021.
A fun novella told from the perspective of an android.
This book was beautiful. It manages to feel slightly off and this is completely appropriate given the narrator. This leads to some really amusing bits of writing.
I thought I had read less this year than I had in recent years but I was wrong. I read 57 books and 19,564 pages in 2021.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Here is a breakdown of books finished by month. I can tell from looking at August and September that I started and finished the Vorkosigan series during those months.
Electronic books continue to be the dominant format.
1 2 3 4 5 6 |
|
Fiction dominated this year.
1 2 3 4 5 |
|
Here is the star rating distribution.
1 2 3 4 |
|
I used to be pretty good at capturing some thoughts upon completion of a book. I haven’t been doing a great job of that. I’d like to do better this year.
We’ll see what that entails but it might take the form of having more discipline around sending out some thoughts in the newsletter.
Have any book recommendations? Please shoot me an email or leave a comment.
]]>You might write tests as a way of driving the design of your software. Other tests might be written in response to a discovered bug and, if written first, those tests you know when you’ve fixed the bug and act as guardrails preventing the reintroduction of that bug. Tests can also be used to confirm you haven’t changed behavior while refactoring.
Tests can also be used as documentation. Unlike non-executable documentation, tests will always match the implementation’s behavior.
An example in a comment or other documentation deserves to be in a test. Take the following sketch of a Clojure function:
1 2 3 4 5 6 7 8 9 |
|
The docstring has examples in it to aid humans in understanding its behavior. These examples are useful! But they stop being useful and start being dangerous when they stop being accurate.
We can use unit tests to keep examples like this correct. You can write comments near the assertions letting future readers know about the documentation that needs to be updated if behavior changes.
1 2 3 4 5 6 7 |
|
Any example in a comment or other non-executable documentation should be an assertion in a unit test. You’ve already taken the time to document the behavior; take the time to figure out how to document it in a way that will fail if the behavior changes.
]]>Imagine the following.
A new developer joins your team and asks a question about how the code resolves config values. You are unsure of the details so you pair up with the new teammate to dig into the code.
You know the codebase uses a relatively simple key-value pair concept for configuration. It reads keys and values from a known files and, based on some rules, either ignores or overrides values when keys are duplicated across files.
config-value
is the function that looks up the value for a particular configuration key, represented as a string
.
This function takes three arguments: an in-memory representation of the configuration files, the key to lookup, and the mode to operate in.
You know the mode is important in influencing how config resolution works but you don’t remember the details.
Luckily for you and your pair, the codebase has plenty of unit tests. The two of you dive in and look at some tests, hoping to understand how config resolution works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
It is great that these tests exist but they could be clearer. They aren’t terrible but you have to work a bit understand what is happening.
When reading (= "2" (config-value config "b" :dev))
, what does "2"
represent?
What does "b"
mean?
You have to either keep the value of config
in your brain or keep glancing up in the file to recall what it is.
This isn’t great. This adds cognitive overhead that doesn’t need to be there.
There are a few ways these tests could be improved One way is through using better constants. Let’s do a quick rewrite.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
These are the same tests but with different constants.
Those constants make a huge difference.
This change has made the tests more legible.
You no longer need to remember the value of config
or keep glancing up at it to understand the assertions in a test.
You can read (= "from development" (config-value config "in dev+app" :dev))
and have a pretty solid idea that you are looking up a key found in both development.conf
and application.conf
and while in :dev
mode expect the value from development.conf
.
The new constants provide clues about what the test expects. You can read and understand the assertions without keeping much state in your head.
This increases the legibility of the tests and is useful when a test fails. Which of the following is clearer?
1 2 3 4 5 |
|
1 2 3 4 5 |
|
The second one is clearer. You can read it and form a hypothesis about what might be broken.
Well chosen constants reduce the state a person needs to keep in their head. This makes tests easier to understand. Good constants also make test failures easier to understand. Just like good variable names, good constants increase the readability of our tests.
It is well worth placing some extra thought into the constants found in your tests.
]]>Here are links to my previous end-of-year reflections: 2013, 2014, 2015, 2016, 2017, 2018, and 2019.
I’ve continued to keep track of my reading using Goodreads. My profile has nearly the full list of the books I’ve read since 2010. Here is my 2020.
Last year I wrote:
I was encouraged by how many non-fiction books I read this year and how many of them ended up earning a five star rating. I’d like to continue that trend of reading high-quality non-fiction books.
I’ve also been reading a lot of books but I haven’t always been the best at trying to consciously apply the lessons from those books. I’m going to try to improve that this year.
Those are pretty fuzzy goals but I’m alright with that.
I’ll come back at the end of this article and reflect on if I hit it or not.
Here are my five star books from 2020. The titles are affiliate links to Amazon. If you click one and make a purchase I get a small kickback.
If I wrote a review on Goodreads then the my review
link will take you there.
In the last couple of years, I’ve been writing fewer reviews on Goodreads than in the past so many books do not have a review there.
If you’re missing these reviews, I have started sending out an email every month or two and it frequently includes small reviews of what I’ve read since the previous email. You can subscribe to that here.
Here are the 2020 five star books:
This is an excellent dose of wisdom about climbing and improving your performance. It does this through suggestions of how to change your mental relationship with climbing. Improving is about putting in the work, reflecting, and trying hard.
I really enjoyed this book and made hundreds of highlights while reading it on my Kindle. I’d suggest reading reviews on Goodreads and seeing if it is something that would be interesting for you.
This was a good book that, unlike what the subtitle claims, did not transform my sex life. But I didn’t go into it expecting that. I’m not the main audience for this book but still got some value from it. I particularly enjoyed the parts that talked about stress, responses to stress, and emotional systems.
This book is about psychedelics, such as LSD and psilocybin. It combines the history of these substances, old and new research being done with them, and sort of a travelogue of Michael Pollan’s growing experience with these substances.
I’ll just link to a friend’s review of this book.
I devoured all of her writing this year, both fiction and non-fiction, and the highlights are above. None of her writing earned less than four stars.
Between starting and finishing writing this article, I learned she published a new short story, Zikora, and immediately read it. It was pretty great.
One of the reasons I enjoy reading fiction is that it provides a window into the experiences of others. Chimamanda Ngozi Adichie’s writing does exactly this and does it with beautiful prose and compelling stories.
This was a reread of the first Neal Stephenson book I read. I wanted to reread this book as I had been recommending it as a relatively short introduction to Neal Stephenson’s writing but I was second guessing how much I enjoyed it.
I was wrong to second guess that. This story was still great the second time through. This book covers so much and feels prescient despite being read 25 years after it was originally published (February 1995).
Octavia Butler builds a new religion in this series and, honestly, that religion is tempting. These are fantastic science fiction reads that explore human connections and what we could be as a species.
These are books that for some reason I didn’t give five stars but I still think they are worth recommending. All links below are to Goodreads.
This book was weird and I enjoyed it. You follow a character that lives in a weird, infinite building made of corridors lined with statues.
This covers the American political system and how we got to our modern form with deeply polarized parties. I thought it was a pretty interesting read.
I read this at the very beginning of 2020 and think that everyone should read it. I highlighted a ton of passages and plan on going back and reviewing those passages.
I read this at the very beginning of 2020 and highlighted a ton of passages. The book is about listening and how we do a bad job at it. It includes suggestions about how to get better.
Pair this book with I hear you, a book I read last year, and you’ll have the tools to become a better listener.
This was a stupendous science fiction read. It takes you on a wild journey into a far future where sentient beings can exist in software.
This was very close to receiving five stars but I kept getting bogged down in some of the explanations. I know this is why some folks enjoy hard science fiction but that isn’t why I’m reading these stories. This book delivers an interesting, complex, and very speculative far future. If the blurb sounds interesting to you and you’re willing to put up some with advanced theoretical (real? fake? I don’t know) physics then pick this book up.
I read 43 books and 12,093 pages in 2020. The data also doesn’t capture three books that I’ve started but have yet to finish.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Last year marks a decade of me tracking my reading and it was the second lowest page count in that decade. For many reasons 2020 was an unforgettable year and one where I spent a lot of time at home.
I would have thought that would have lead to a large number of pages read but I think much of my time ended up being taken up by non-book reading activities. For better or worse (probably worse), a lot of my time was spent reading articles about the on-going global pandemic, the USA election, and the other non-stop news cycle of 2020. Between that and the increase in newsletters and podcasts I’m consuming, I’m not that surprised my book reading has taken a hit.
Here is a breakdown of books finished by month.
This graph tells a slightly different story than the one I presented above. I did not finish many pages in January through March, the pre-pandemic time period in the United States.
Those months I was extremely dedicated to training for climbing and was starting a new relationship. I’m very happy both of those took up my non-working hours during those months.
I was still commuting to an office from January till mid-March and would have expected more pages finished on the train. I’ll blame podcasts for that as this year I did start listening to those while commuting, since I can enjoy those while walking to and from the train as well.
The number of books read in February is high because I read a short story collection where each story was published individually on Amazon.
Unsurprisingly, electronic books continue to be the dominant format.
1 2 3 4 5 6 |
|
Below is the breakdown of fiction vs non-fiction books. Fiction started to regain its dominance after having non-fiction catch up in 2019.
1 2 3 4 5 |
|
Here is the star rating distribution.
1 2 3 4 |
|
I succeeded in reading a solid number of non-fiction books that earned a high rating. I read fewer non-fiction books than fiction but managed to have more 5 star ratings. I’m going to count this as successfully hitting the non-fiction part of my 2020 goal.
Did I get better at applying the lessons from books? Not at all and I barely even tried to do so. Definite failure here.
I have quite a few unread books sitting on my virtual and physical bookshelf. This feels like setting a really low-bar but this year I’d like to read some of these unread-but-owned books.
I’m also planning on reading at least one book on writing and one book on climbing. This goal is almost a subset of the above goal as I have books on both these topics sitting on my shelf.
It is interesting to have been collecting this data for a decade now. I haven’t done much in the way around looking at multi-year trends but I think it might be interesting to do so.
If you have a book recommendation, feel free to reach out and contact me.
]]>native-comp
feature of Emacs might improve the Magit status refresh time.
This reddit thread was the first time I had heard of the native-comp
feature.
This feature lives on the feature/native-comp
branch of the Emacs repository and it compiles Elisp code into native code.
Many users have reported noticeable speed improvements using it.
The official development log and Emacs Wiki have more information about it.
I’ll provide more information about getting native-comp
working on macOS after I answer the Magit speed question.
The quick answer is that running Emacs with native-comp
improved the refresh times of the Magit status buffer.
Below is a table of the various times.
1 2 3 4 5 |
|
Using native-comp
, we’ve cut off about 0.85 seconds.
That is a pretty solid improvement.
Even still, that isn’t fast enough for how often I use Magit so I’ll be sticking with my Magit setup with many sections removed.
As a caveat, the timing with native-comp
also includes upgrading Emacs from 26.3
to 28.0.50
(so I could have native-comp
) and Magit from 20201111.1436
to 20201212.929
.
As a result, the comparison to full magit-status without native-comp
isn’t entirely fair as multiple variables have changed.
The comparison to time with sections removed is fair as I’m still using that setup (but with native-comp) and the timing is pretty much the same.
native-comp
on macOSTo enable native-comp
you need to build Emacs from source.
I’ve done this before on Linux systems but this was the first time I’ve done this on macOS.
When browsing reddit, I found the build-emacs-for-macos project which has some helpful instructions for doing this.
I followed the instructions from the readme and picked the latest known good commit from this issue (at the time I did this be907b0ba82c2a65e0468d50653cae8a7cf5f16b
).
I then updated my init.el based on instructions from in the build-emacs-for-macos
project.
I haven’t had any issues since switching to this very new Emacs. I don’t have numbers to back this up but it does feel faster.
I’d recommend giving the native-comp
feature of Emacs a shot.
It wasn’t terribly challenging to get setup and it is nice to get a glimpse of what the future of Emacs might be.
That future is a bit snappier.
Unfortunately, refreshing the magit-status
buffer is sluggish when you are working in a large repository.
A few months ago, I became sick of waiting and investigated how to speed up refreshing the status buffer.
After doing some research, I learned about the magit-refresh-verbose
variable.
Setting magit-refresh-verbose
to true causes Magit to print some very useful output to your *Messages*
buffer.
This output shows how many seconds each step of magit-status
takes.
Here is the output for the large repo that caused me to look into this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
The total time is found in the last line and we can see it took four seconds. Four seconds is an incredibly long time to wait before interacting with Magit.
You can change how much work Magit does by removing functions from the magit-status-sections-hook
with remove-hook
.
I looked at the timings and and tried removing anything I decided was slow and something I didn’t think I’d miss.
For me, that list includes magit-insert-tags-header
, magit-insert-status-headers
, magit-insert-unpushed-to-pushremote
, magit-insert-unpushed-to-upstream-or-recent
, and magit-insert-unpulled-from-upstream
. I also removed magit-insert-unpulled-from-pushremote
.
You remove a function from a hook by adding elisp similar to (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header)
to your Emacs configuration.
I use use-package to configure mine and below is what my magit
section looks like.
Lines 20-25 remove the hooks.
I also hard-code magit-git-executable
to be the full path of the git
executable on line 5 because folks said this made a difference on macOS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
After this change, my magit-status
buffer refreshes in under half a second.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
What did I lose from the magit-status
buffer as a result of these changes?
Here is screenshot of the original buffer.
And here is the buffer after.
The difference is drastic1. And so is the speed difference.
The increased speed is worth losing the additional information.
I interact with git
very often and much prefer using Magit to do so.
Before these changes, I found myself regressing to using git
at the command line and I don’t find that to be nearly as enjoyable.
Since I’ve made these changes, I’m back to doing 99% of my git
interactions through Magit.
Don’t settle for slow interactions with your computer. Aggressively shorten your feedback cycles and you’ll change how you interact with the machine.
This post was written with Magit version 20201111.1436
and Emacs 26.3
on macOS 10.15.7
.
I’ve been using these changes for a few months but do not remember or have a record of what Magit version I was using at the time I originally made these changes.
edit on 2020/12/15: I recently upgraded Emacs to tryout the native-comp work and can report this still works with with Emacs 28.0.50
, Magit 20201212.929
, and Git 2.29.2
running in macOS 11.0.1
.
Warning: This reduces the information Magit shows you. The status buffer will be blank if you have no changes. I find this tradeoff to be worth it.
I created it because I was reading Dune for the first time and there were many unfamiliar words. These words could not be looked up by my Kindle because they were not found in any of on-device dictionaries. These words were in Dune’s glossary but flipping back-and-forth to that on a Kindle was a huge pain.
I initially worked around this by printing a word list from Wikipedia and carrying it with me. This was better but it was still annoying.
I was so annoyed that I took a break from reading to figure out how to create a custom Kindle dictionary. At the time, there wasn’t a ton of great information online about how to do this.
Eventually, I found Amazon’s Kindle Publishing Guidelines and, referencing it, managed to figure out something that worked. The link in the previous sentence is to the current documentation which is much nicer than the mid-2013 documentation. The earlier documentation left me with questions and required quite a bit of experimentation.
Using the mid-2013 documentation, I developed some Clojure code to generate my dictionary. Doing this in 2013 was annoying. The documentation was not good.
I recently read Greg Egan’s Diaspora and found myself wishing I had a custom dictionary. I took a break from reading and packaged up Diaspora’s glossary into a dictionary. I could have stuck with my 2013 generator but I decided to update it and write this article about creating a Kindle dictionary in late 2020.
The new documentation is a bit better but it still isn’t great. Here is what you need to do.
Below are the steps to building a dictionary.
.opf
file.There really are no set instructions for this. Source your words and definitions and store them in some format that you’ll be able to manipulate in a programming language.
I’ve sourced words a few different ways. I’ve taken them straight from a book’s glossary, a Wikipedia entry, and extracted them from a programming book’s source code.
Below is the basic scaffolding of the html file Amazon requires along with some inline styles that I think look decent on devices. This has some extra stuff in it and also doesn’t contain everything Amazon specifies. But it works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
The [PUT THE WORDS HERE]
part gets filled in with the markup for all of your words.
The basic structure for an entry looks like the following.
1 2 3 4 5 |
|
Every word has an <idx:entry>
block followed by a <hr>
.
These two elements together comprise a single entry.
The name
attribute on the <idx:entry>
element sets the lookup index associated with the entry.
Unless you are building a dictionary with multiple indexes, you can pretty much ignore it.
Whatever value is provided needs to match the value found in the .opf
file we’ll make later.
The scriptable
attribute makes the entry available from the index and can only have the value "yes"
.
The spell
can also only be "yes"
and enables wildcard search and spell correction.
The markup you use inside the idx:entry
element is mostly up to you.
The only markup you need is the <idx:orth>
node.
Its content is the word being looked up.
The rest of the markup can be whatever you want.
I wrap the term in a dt
and the definition in dd
because it just feels like the right thing to do and provides tags to put some CSS styles on.
I wrap the dt
element in an h5
because I couldn’t figure out what CSS styles would actually work on my Kindle voyage to put the term on its own line.
It isn’t that I don’t know what the styles should be but my Kindle did not respect them. Figuring out stuff like this is part of the experimentation required to produce a dictionary that you’re happy with.
There is additional supported markup that provides more functionality. This includes providing alternative words that all resolve to the same entry, specifying if an exact match is required, and varying the search word from the displayed word. Most dictionaries don’t need these features so I’m not going to elaborate on them.
This is just a requirement of a Kindle.
Create a html file called cover.html
and substitute in the appropriate values.
1 2 3 4 5 6 7 8 9 |
|
Amazon wants you to provide an image as well but you don’t actually have to do this. You probably need to do this if you actually publish the dictionary through Amazon1.
This is also a requirement of the Kindle publishing guide. There isn’t any special markup for doing this.
Just make another html file and fill in some appropriate details.
This isn’t a requirement but I include another page that explains how to use the dictionary. Again, this is just a html document with some content in it.
.opf
file.This is one of the poorly documented but extremely important parts of making a Kindle dictionary. This is a XML file that ties together all the previous files into an actual dictionary.
Make an opf file and name it whatever you want; in this example we’ll go with dict.opf
.
Below is the one I’ve used for the Diaspora dictionary. If you’ve created an image for a cover then lines 7 and 15 are the important and line 15 should be uncommented.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
An import element in this file is the <DefaultLookupIndex>
element.
The <DefaultLookupIndex>
content needs to contain the same value from the name
attribute on your <idx:entry>
elements.
The <DictionaryInLanguage>
and <DictionaryOutLanguage>
tell the Kindle the valid languages for your dictionary.
The other elements in the <metadata>
should be pretty self-explanatory.
The <manifest>
gives identifiers for the various files you’ve made in the previous steps
The commented out <img>
shows how you’d add the cover image if you opt to have one.
For sideloading dictionaries onto Kindles, it is not required.
The <spine>
section references the <item>
s from the <manifest>
and specifies the order they appear in your book.
I honestly don’t remember why the <guide>
section is in there or what it is doing in this example.
I’m guessing that is what causes there to be an index with the word list in the dictionary but I haven’t tried removing it and the documentation doesn’t talk about it.
I only have it there since I had it in earlier dictionaries I made.
The publishing guidelines (as of October 2020) tell you to combine the previously created files together using the command line tool kindlegen
.
The problem with those instructions is that Amazon doesn’t offer kindlegen
as a download anymore.
If you want to use it, you can still find it through the Internet Archive.
Instead of following the publishing guidelines, we’ll use Kindle Previewer to finish making the dictionary. It is pretty straight forward.
File > Open
.dict.opf
file and open that.File > Export
and export it as a .mobi
file.The conversion log will complain about a couple things such as missing cover.
As long as these are just Warnings
it doesn’t matter.
I’ve found the preview in this app doesn’t match what it looks like on your device so take it with a grain of salt.
Finally, put the dictionary onto your Kindle. You can do this by either using a USB cable or by emailing it to your Kindle’s email address.
Once it is on your Kindle, open it up and double check that the formatting is correct. Next, open the book you’ve made it for and try looking up a word. If the lookup fails or uses another dictionary, click the dictionary name in the pop-up to change your default dictionary to yours. Now when you try to look up a word, your dictionary is searched first.
The great thing is that if a word isn’t in your dictionary then the Kindle searches the other dictionaries2. This feature is great as it lets your dictionary be very focused. Hopefully Amazon doesn’t remove this feature.
It was interesting creating another dictionary so long after I made my first couple. Some of the new features, like the ability to require an exact word match, would have been useful for my second dictionary. The actual markup recommendations have changed over the years but luckily my Dune dictionary still works. I’m not constantly checking that it works, so if Amazon had changed something and it broke, I probably wouldn’t notice until someone reported it.
The Kindle documentation is much better now compared to 2013 but it still isn’t great.
It is also a bummer that kindlegen
is gone.
It was nice to be able to convert the input files from the command line.
I also think this means you can no longer make a dictionary from a Linux machine as I don’t remember seeing Kindle Previewer support.
If you’re ever in a situation where you think a custom dictionary would be useful, feel free to reach out.
Go forth and make dictionaries.
]]>These weren’t created to solve large problems in the world. There is no plan to make any money with them. As of October 2020, Default Equipment doesn’t even work for other people (though it could, send me a message if you’d like to use it and I’ll get around to it).
Each was created to fix a minor annoyance in my life and, because these tools can live on the Internet, they can fix the same minor annoyance in other lives.
With an increasing amount of software in the world, being able to write software is nearly sorcery1. As a developer, you can identify a problem in the world and then change the world to remove that problem. And, depending on the problem, you can remove it for everyone else.
Software developers aren’t alone in being able to identify problems and remove them through creation. Carpenters can build shelves for their books. Cooks can prepare food to remove hunger. You can come up with nearly an infinite number of other examples.
The difference is that a solo developer can solve problems for an unknown number of other folks. This is enabled by the Internet enabled ease of distribution. This is very powerful.
Developers can expose their solution to others through a web application. Desktop or mobile applications can be distributed through various app stores or made available as a download. Source code can be made available for others to run. Being able to distribute easily and cheaply is a game changer.
A developer’s change to the world might be a minor improvement. Photo Fit might never be used by anyone besides me. But it is still out there, making the world slightly better. It is available for someone to stumble upon when they are also annoyed by the same problem.
It felt good to write these tiny, useful programs. If you scope them small enough, there is a definitive ending point2. This lets you feel that finishing-a-project satisfaction quickly. The small size also allows you experiment with new techniques and tools without committing to a large and ongoing commitment.
I wrote both Photo Fit and Default Equipment in TypeScript. Before the beginning of summer, I didn’t know TypeScript and had little exposure to Node.js. Now I have some experience with both and gained that while making small improvements to my life and potentially the lives of others.
If you haven’t developed software to solve a small problem recently, I’d recommend doing it. Don’t hesitate to remove a problem that feels silly. Removing those problems can still make your life slightly better and gives you an opportunity to learn. It feels good to remove an annoyance from your life. If you can, make that software available to others so their lives are improved as well. Take advantage of the power of easy distribution to improve the world and not just your tiny slice of it.
selecta
a list of text on stdin, it helps you make a choice from items in that list, and then selecta
prints that choice to stdout.
Here is an example of me using it to help me narrow in on what file I’d like to pass to wc
.
In this example, I search for markdown files using ripgrep
(rg
), type part of a filename, hit enter to select the match, and then see the wc
stats of that file.
This isn’t the greatest example of using selecta
but it adequately shows what it does.
Some number of years ago, I wrote a script called connect-db
.
This script used selecta
, along with grep
, sed
, and cut
, to provide a very pleasant command-line experience for connecting to known databases.
My coworkers and I used this script frequently.
By combining selecta
with other stdin/stdout friendly command-line tools you can build really enjoyable, time-saving tools.
Selecta is a useful utility to add to your toolkit.
When I made it my background, my phone1 zoomed in to make it fit the portrait orientation of the phone.
This is not great. I don’t want a zoomed in version that fits my vertical phone. I want to see the whole photo with black bars at the top and bottom
I tried to find a way to add these bars using my phone. I couldn’t find an easy way.
At this point, a reasonable solution would have been transferring the photo to a computer, editing it, and transferring it back to my phone. I didn’t do that. Instead, I wrote a little TypeScript2 web app that adds the bars for you. You open the website on your phone, select an image, and then download a properly sized image.
The tool uses the canvas API and does all of the work in the browser itself. It was a fun, bite-sized project and it gave me an excuse to write some TypeScript and do some web programming. This was the first time I’ve written TypeScript since learning it and I haven’t done any web programming in a while.
Making Photo Fit was not a fast approach to changing my phone’s background. But, now the tool exists and anyone, including future me, can quickly resize their photo from the comfort of their own phone.
Photo Fit is live and available for others to use. I’ve only tested it on my own phone and desktop browsers. It might not work! If you do try it and something weird happens, plese let me know.
Flaky tests erode your team’s confidence in your system. They cause folks to get in the habit of not trusting the output of tests. This discourages people from writing tests as they stop seeing them as something that improves quality and instead view them as a drag on productivity.
Flaky tests are often hard to fix. If they were easy to fix, they wouldn’t have been flaky in the first place. One difficulty in fixing them is that the failures are often hard to reproduce.
Often, the first step in fixing a flaky test is to write a script to run the tests multiple times in a row. If you are using Bazel as your build tool you don’t need to write this.
Here is an example bazel
1 command for helping you recreate flaky test failures.
bazel test --test_strategy=exclusive --test_output=errors --runs_per_test=50 -t- //...
The above command is running all the test targets in a workspace and each flag is important.
--runs_per_test=50
is telling Bazel to run each test 50 times.--test_output=errors
is telling Bazel to only print errors to your console.-t-
is a shortcut for --nocache_test_results
(or --cache_test_results=no
).
This flag tells Bazel to not cache the test results.--test_strategy=exclusive
will cause tests to be run serially.
Without this, Bazel could run your test targets concurrently and if your tests aren’t designed for this you may run into other failures.Flaky tests are terrible and you should try not to have them. Try your best to have reliable tests.
Has some variation of the above happened to you?
It doesn’t happen to me anymore because now my computer tells me when any long running process finishes. This might sound annoying but it is great. I no longer feel guilty1 for dropping into Slack and can immediately get back to the task at hand as soon the process finishes.
I’ve done this by enhancing on my setup for showing the runtime of the previous command in my prompt. You don’t have to read that article for the rest of this one to make sense, but you should because it shows you how to add a very useful feature to your prompt.
Below is the code that causes my computer to tell me when it finishes running commands that takes longer than 30 seconds.
It is found in my ~/.bashrc
.
An explanation follows the code snippet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Bash-Preexec triggers the preexec
, immediately before a command is execute, and precmd
functions, immediately before the shell prompt reappears.
Those two functions are enough to figure out how much time has elapsed while a command ran.
You setup Bash-Preexec by downloading bash-preexec.sh and sourcing it in your ~/.bashrc
.
preexec
is passed the command being ran and it captures it in _last_command
.
It also captures the current number of seconds the shell has been running as _timer
.
precmd
uses the value in _timer
to calculate the elapsed time in seconds and then calls the function _maybe_speak
with this as an argument.
It also does the work required for showing the elapsed time in my prompt.
If the elapsed time is greater than 30 seconds then _maybe_speak
uses cut
to discard the arguments of captured command, leaving me with the command itself.
It then uses say
to produce an audible alert of what command just finished.
I discard the arguments because otherwise the say
command can go on for a long time.
say
is a tool that ships with macOS.
I haven’t gotten around to it yet but I’ll need to use something else on my Linux machines.
You may have noticed that I run say
in the background and in a subshell.
Running it in the background lets me continue interacting with my shell while say
finishes executing and running it in a subshell prevents text from appearing in my shell when the background job finishes.
With this setup, I can kick off a slow compile or test run and not feel so bad about dropping into Slack or reading Reddit. It is wonderful and I’d recommend it (though, I’d more strongly recommend not having commands that take a while to run).
A hangboard allows you to apply stress to your fingers in a measured and controlled fashion. It is a vital tool for a climber who is serious about getting stronger. It is also a great rehab tool for coming back from injuries.
Below is my hangboard.
As you can see from the photo, I’ve hung mine using a doorway pull-up bar and a bunch of hooks. This lets me easily take it down and causes no permanent damage to anything in my apartment. The towels are there to make sure the door frame isn’t crushed by any of the hard pieces.
Originally, I followed this video to mount it using some pipe and shoving the pipe into the pull-up bar. This setup made me uncomfortable as the forces on the pull-up bar were far away from the intended location. This resulted in a lot of flexing and I was concerned about how the pull-up bar was acting on the frame.
I searched online for other ideas and saw a setup that used hooks. This was appealing to me as it moves your weight under the bar. A quick trip to Home Depot and a bit of easy construction and now I can keep up my finger strength when stuck at home. Here are the steps to build one.
The board and hook method was much easier to construct than the other pull-up bar method and feels much more solid. The pull-up bar isn’t rated for too much weight, so I’m not going to do any super heavy, two-handed hangs but it is plenty solid for other hangboard exercises.
If you’re a climber and don’t want to permanently mount a handboard, I’d highly recommend this. If you don’t own a hangboard, I pick up something from Tension Climbing. Their wooden boards are easy on the finger tips and have all the edge sizes you’ll need.
]]>I’m fairly certain the following scenario has happened to every terminal user. You run a command and, while it is running, realize you should have prefixed it with
time
. You momentarily struggle with the thought of killing the command and rerunning it withtime
. You decide not to and the command finishes without you knowing how long it took. You debate running it again.For the last year I’ve lived in a world without this problem. Upon completion, a command’s approximate run time is displayed in my prompt. It is awesome.
I’ve been living without the above problem since sometime in 2014 and not having that problem is still awesome.
I have made some changes since 2014.
One change was switching to using Bash-Preexec instead of directly using trap
and $PROMPT_COMMAND
for calling functions to start and stop tracking runtime.
Bash-Preexec lets you trigger a function (or multiple) right after a command has been read and right before each prompt.
The usage is pretty straight forward.
In the most basic case, you source bash-preexec.sh
and then provide functions named preexec
, which is invoked right before a command is executed, and/or precmd
, which is invoked just before each prompt.
bash-preexec.sh
can be downloaded from its repo.
The changes required to move to Bash-Preexec pretty pretty minimal.
The other change was introducing the script, format-duration by Gary Fredericks, to humanely format the time.
This script converts seconds into a more readable string (example: 310 to 5m10s
)
Here is a screenshot of everything in action (with a reduced prompt, my normal one includes git and other info).
Below is a simplified snippet from my .bashrc
that provides runtimes using both of these additions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
No more wondering about the runtime of commands is great.
Introducing format-duration
made reading the time easier while Bash-Preexec made reading the implementation easier.
I highly recommend setting up something similar for your shell.
See all of my remote/working-from-home articles here.
Retrospectives are a useful type of meeting to have periodically with your team. There are many different formats of retrospectives.
One of them can be summarized in the following steps:
What went well?
and What needs improvement?
Let’s talk about each step and see how each works with an co-located or remote team.
This step is self explanatory. If you are an in-person team, then this is gathering everyone together in a room for some allotted about of time. If you are a remote team, or have remote folks on your team, then this is gathering everyone together in a video conference.
Preferably everyone in the retro is communicating in same way. This means if anyone is remote, it is preferable that everyone join the video conference from their own computer instead of using a single screen and video from a shared conference room. My earlier article about tips for remote meetings goes into more details on this topic.
Everyone using the same communication method puts everyone on the same page and dramatically improves the experience for the remote folks. With a mixed group, we’ll want to use some remote collaboration tools anyway, so it is useful for everyone to have their own computer with them. They might as well use it for video communication as well.
This part doesn’t differ between an entirely in-person meeting, mixed, or entirely remote meeting.
Take the time to set the stage for the meeting. Remind everyone that we’re here to improve and to listen with an open mind. Remind everyone to try to not make things personal and not take things personally. This is a good time to read the Prime Directive.
This is also a good time to set the boundaries of the discussion. What is the retrospective covering? Is it covering the last few weeks? The last quarter? The new working from home experience? Pick a topic so everyone in the meeting focuses on the same things.
In this step, we will answer the questions What went well?
and What needs improvement?
and use those answers for discussion in the remainder of the meeting. Timebox this step to 5 to 10 minutes.
In an in-person setting, this is often done through the use of Post-it notes. Give each attendee a marker and a stack of notes and have each person write down as many answers as they can come up with, one per post-it note, to the two questions. Dedicate a section of a whiteboard or wall for each question and have people bring the generated answers to the respective sections. Try to group the answers by topics.
With a remote meeting, you don’t have the physical whiteboard and cards. That is perfectly fine! Once you figure out your remote collaboration tools, this part of the retrospective isn’t difficult.
I’ve mostly done remote retrospectives using Trello. Trello works great for this as it is multi-user and does a great job of presenting lists to a group. Here is how previous teams I’ve worked with setup Trello for remote retrospectives.
First, make a Trello board and make sure everyone has an invite to view and edit the board. Second, add the following columns to the board.
The first column is for Step 2 of the process and is there to remind everyone why we’re all spending time in this meeting.
Columns two and three are used in this step. Have attendees add cards to these columns as they come up with answers If anyone notices duplicates during this time frame, move them near each other by dragging them up or down in the column. If you notice someone else has already put a card that you’d put up there, don’t bother putting it down again (this differs from the in-person meeting).
This step sneaks into the remote retrospective and is missing from the in-person retro. In the in-person retro, duplication of post-it notes serves as this voting stage.
Once all the answers have been generated, or time is up, it is time to vote on what will be discussed in the next step.
Only have people vote on the What needs improvement?
answers.
There are at least two ways of doing this in Trello but my favorite is having attendees hover their mouse cursor over the card and then hit space bar
1.
This sticks their avatar on the card (in Trello speak, I believe this is called joining a card).
You can either restrict folks to a certain number of votes, say 3, or let them go wild and vote as many times as they want.
I haven’t found the outcomes to be much different and find infinite votes more fun.
Once voting is finished (again, timer or when it seems to have reached an end), have one person sort the cards by number of votes with the highest votes at the top of the list.
With in-person or remote retros, go over the answers to What went well?
first.
This starts the discussion with positive feelings.
This part usually goes pretty fast as we’re just celebrating wins and not having a long discussions about them.
Next, start discussing the answers to What needs improvement?
For each topic being discussed, set a five minute timer. At the end of the five minutes, do a quick poll of the attendees on if the topic should be continued or not. If it should be continued, start a three minute timer and continue discussion. At the end of those three minutes, repeat the vote for continuing or not.
Throughout the discussion, try to be mindful of people dominating conversation and give everyone a chance to voice their thoughts. Try to figure out some next steps to take to actually start making improvements on what needs to be improved.
The above is generic advice for remote or in-person retros. When you’re running a remote retro using Trello, it can be useful to do the following as well.
You should add two more columns, Next Steps
and Discussed
, to the right of the What needs improvement?
column.
Since your cards are sorted in the What needs improvement?
column, you’ll always be talking about the top card.
As discussion finishes, move it from the top of the What needs improvement?
column into the Discussed
column.
As Next Steps
are discovered, add cards to the Next Steps
column and assign the people responsible for following up to the card.
Below is an example of those three columns after discussing two cards.
When voting on continuing discussion or not, it can be useful to have a hand signal for taking the vote and for continuing or ending the discussion. We’d do a quick thumbs up or thumbs down and if half the team wants to keep going then we’d seamlessly start the next timer.
Retrospectives can be a very handy tool for a team’s continuous improvement. If time isn’t provided for reflecting, then reflecting does not happen and this makes improving harder.
Remote retrospectives provide a challenge since most of us only have experience using physical sticky notes or whiteboards for collecting answers. We don’t need to recreate the same form factor for remote retrospectives. Using remote collaboration tools, such as Trello, that don’t recreate the sticky-note-on-wall experience can lead to initial confusion but, once familiar with them, the experience is pleasant and allows for greater participation.
How is participation increased? Well, in an in-person retrospective you often are unable to read what everyone else has stuck up on the wall because of physical distance. With a remote retro, you’re able to read every answer added to the lists.
Don’t be afraid of running a remote retrospective. They can be incredibly useful.
See all of my remote/working-from-home articles here.
With the the new coronavirus spreading through the world, more people are either choosing or are being forced to work from home. From 2013 to 2018, the companies I worked for were entirely remote. For the rest of my professional career, 2007 to 2013 and 2018 to now (March 2020), I’ve also frequently worked from home.
I’ve managed to be very effective at it and I think others can be as well.
After years of working in an office, transitioning to working from home isn’t easy. I had difficulty with the transition and people I’ve mentored have as well. I think most people will be able to be effective at home, assuming their workplace is supportive, if they try to get better at it. With a supportive company or team, once you get used to working from home you probably find yourself getting more done.
The key word in the sentence “I’m working from home” is working. You are going to be working where you spend a lot of your non-work time. This can be a difficult mental transition. Physically switching to an office environment can help switch your brain into work mode and now you no longer have that. Don’t worry, it might feel rough in the beginning but you will get better at it.
I’ve written more articles about working remotely and I’d recommend you read those as well. This article is primarily targeted at the person not making a permanent change in their work from home status. My Guide to Distributed Work is a bit more targeted at someone that is permanently choosing to work at home or in a position of power to influence work from home policies at a company. I’d recommend that you read it as well as many of the subjects it talks about are generally applicable. It steps through some of the pros and cons of remote work and links to other writing on the topic.
Below is a hodgepodge of tips for working from home.
In my years of remote work, I’ve always managed to have a dedicated space for work. In some apartments, this was a corner of a room where I put a desk and faced a wall. In other apartments, I’ve been privileged enough to have a dedicated room for an office.
If you aren’t planning on working from home permanently, or very frequently, then you probably don’t want to spend a significant amount of money setting up a work area. This probably means you don’t want to find a home with a dedicated office and you may not want or be able to dedicate a portion of a room to a desk1.
Whatever your living arrangement is, I’d encourage you to figure a way to have a regular spot to work at while you are working. Having a regular spot to work from will help your brain turn on and off from work mode.
Setting up a home workspace can be as low cost as using a tv tray or folding table2 with a chair. Your setup could be as elaborate as getting a height adjustable desk with large monitors. It could be something else entirely.
Find something that works for you and stick with it.
Beyond a dedicated space to work, make sure you have a reliable internet connection. If you can, use Ethernet as it is generally better than WiFi. I’ve never had a situation where I could use Ethernet and have found that having a good router is enough to make my WiFi reliable.
If you live with others that will be at home while you need to work, you should have a discussion with them about boundaries. You are at home to do work and that expectation needs to be set. You may be able to do some household chores during breaks or take other breaks with cohabitants but everyone in your living area needs to understand you are at home to work.
If you have children that might have a particularly hard time with this, it can be useful to use some sort of physical signaling device (examples: a closed door, a light bulb being on, a closed curtain, headphones on) that you should not be interrupted.
This one is obvious but try to minimize distractions. Don’t try to sit on your couch with the TV on and do work. You won’t be doing great work.
If your home is loud and you have difficulty in a loud space, wear some ear plugs or noise canceling headphones.
If cohabitants are distractions, refer to the above section and have that discussion with them about needing space. One technique for dealing with interrupting cohabitants is to schedule time throughout your day for them. You can use these scheduled times as breaks through out your working day.
If you try to get some household chores done while working at home, make sure you schedule time for doing them. This could be putting the time on your calendar or simply setting a timer when taking a break. Regardless of the method, when your time is up, get back to work.
I’ve often found that finishing a short, simple household task can actually jump-start finishing more complicated work tasks. Using that momentum from the household chore can make accomplishing work tasks easier.
Sometimes it is hard to start a task. It can be especially hard if you are new to working at home and not used to working in your environment.
One technique I’ve found useful is the Pomodoro technique. The steps to this technique are below.
I don’t follow those steps strictly and mostly use the trick of setting a timer for focused work. If at the end of the timer I feel like continuing, I’ll reset the timer. If I need a break, I’ll set the timer for a short period of time and take a break.
It was mentioned above, but sometimes doing a small, easy task can jump-start knocking out TODOs. This small, easy task could be something work related or some simple chore around the house.
Text communication is hard. It is often taken more negative than intended. Be mindful of that.
Try to take what your coworkers write in the most positive way possible.
Try to be careful with your own written communication. It sounds ridiculous but emojis can help make you look like less of a jerk and set a friendly tone.
Don’t hesitate to jump on a video or voice call with someone (or a group). Video is a much higher quality interaction than voice and both are much higher quality than text. The downside is the communication isn’t persistent so be sure to write down outcomes of conversations.
Try to sync up with your team (if you don’t have a team, sync up with someone else from the company) at a regular interval. This should probably be at least once every couple days but it can be more regularly. I usually once a day.
It can be easy to feel like an island when you are part of a remote group. Regular sync-ups help reduce that feeling.
Most video conference software allows you to share your screen with others. Some of them even allow others to take control of your machine or treat your screen as a whiteboard.
Take advantage of these features. After learning how to use them, these features can often make remote collaboration as productive as in-person collaboration.
Using technology, you can even pair program with someone from another city.
Google Docs is another great remote collaboration tool. The best meetings I have been part of were meetings where every attendee was editing a shared Google Doc.
When possible, have video meetings over voice only conference calls. The addition of body language through video makes remote conversations much better.
You might want to introduce hand gestures for signaling during video meetings3. On a former team, we had the practice of raising a finger4 when you wanted to speak. This practice helped prevent people from interrupting and speaking over each other. It also let quieter people jump into conversations easier.
As far as I can tell, Zoom is still the winner in terms of video conferencing.
I also recommend using a headset with dedicated microphone for talking through your computer. The sound quality is usually better than using the built-in microphone.
It can be difficult to get good at working from home. It is definitely a skill that is learned through experience and reflection. If you have any questions about working remotely, feel free to reach out on twitter or through email.
Working from home can be a great experience.
I keep my notes in a git repository in my home directory, ~/org/
.
I want my notes to be synced between my computers without me thinking about it.
Historically, I’ve reached for something like Google Drive or Dropbox to do this but this time I reached for git and GitHub.
Below is the script that I ended up cobbling together from various sources found online. The script pushes and pulls changes from a remote repository and works on my macOS and linux machines.
The loop starting on line 38 does the work. Whenever a file-watcher notices a change or 10 minutes passes, the loop pulls changes from a remote repository, commits any local changes, and pushes to the remote repository. The lines before this are mostly checking that needed programs exist on the host.
I keep this running in a background terminal and I check periodically to confirm it is still running. I could do something fancier but this isn’t a critical system and the overhead of checking every couple days is nearly zero. Most of the time checking happens by accident when I accidentally maximize the terminal that runs the script.
I’ve been using this script for a long time now and I’ve found it quite useful. I hope you do too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|