RSSAmplifier

Blog

slinkp blog

slinkp.comRSS feed ↗56 posts

Latest posts

Canarat rebuild / repair finished

The Canarat pedal rebuild / repair is finally done. A few months ago actually, but I just today got around to updating the page . It sounds fantastic and I'm pretty happy with the paint job. Also, it bears a sharkweasel sticker . What could Sharkweasel be? Stay tuned.

The Canarat lives!

Just a quick note to say that the Canarat makes sound again! Very happy about this. A quick video proof! Now all I have to do is redo the useless tone circuit (which is not what I built, strange as that seems ). ... and take it out of the case again …

Cursor and the danger of overpromising

A couple weeks ago, I temporarily switched to using GPT-5 as my exclusive coding assistant model, via Cursor. This was prompted by two developments: First of all, I was curious to try GPT-5, which had some buzz as a new contender the latest state of the art coding model. But …

Programming with Kimi-K2 via Aider (August 2025)

TL;DR Inexpensive, fast, promising but hit some walls; needs a lot of babysitting ¶ Running it: aider --model openrouter/moonshotai/kimi-k2 What's good about Kimi K2 ¶ Once I got into a groove with it, it did some things well: Made frontend changes very quickly and cheaply Did a decent job …

Deepseek R1-0528 + Aider (tried 2025-07-25 and 2025-08-10)

TL;DR Cheap, sometimes slow, unreliable as editor; sometimes wrote good code with bad characters ¶ Using it: aider --model openrouter/deepseek/deepseek-r1-0528 I didn't use Deepseek very long - just part of a day on two occasions- and didn't keep very detailed notes. It was kind of slow and made too …

Programming with Aider + Qwen 3 Coder (2025-07-25)

TL;DR It works. It's cheap. It's VERY slow. ¶ Via OpenRouter, https://openrouter.ai/qwen/qwen3-coder . Start it like this: aider --model openrouter/qwen/qwen3-coder ` It's SO cheap ¶ I only used it for part of a day, but I literally spent a total of $0.10 on Q3C to do …

Programming with Aider: Impressions, Overview

Some rough impression after programming mainly with Aider . I first used it exclusively for about 4 days back in March, using version 0.77 and mostly using Claude Sonnet 3.7. More recently I've been using it . and then again for a week end of July, using 0.80.2 …

Copilot in Emacs

I haven't done anything fancy with integrating AI tools into Emacs, but after playing with Copilot a bit in VSCode, I decided that I wanted to at least get the most basic autocomplete feature working. All I did was install copilot.el in Emacs, and now I can use it …

What I've Been Up To Lately (or, blog posts to come)

I've been doing a lot of different things in the past few months, and have a growing pile of not-quite-publishable draft posts about them. This post is a list of those things, and a promise to myself to write some of them up! I'll add links to this post as …

Recording System Audio Output on a Macbook

Several times I've needed to make a recording of the system audio on my Macbook. Typical reasons are: I'm recording a software demo video, where the software produces audio output. I'm making a video in which I'm narrating over an existing recording or video, so I need to record both …

More pedal rebuild updates, and a successful guitar mod

Welp. The good news is I finished upgrading my danelectro 59XT guitar and it sounds amazing. The canarat is assembled in its new housing ... and not working. As for the others : The compressor is assembled in its new housing, with its new charge pump ... and not working. I've not started …

Spydey - a handy link checker

I just released a new version (0.6.1) of Spydey today. Spydey is a link checker, basically. Written in Python. The reason I initially wrote it (a long time ago) was for quickly finding broken links on sites that I develop. And then I got interested in thinking about …

Rebuilding old DIY effects pedals, update April 2025

I've updated the homemade effects pedals page with progress - mainly, lots of photos, and info about the paint experiments I've gradually done over the past few months, which was a nice little crafty project and learning experience. I've gathered some better tools, found most of the parts I need, assessed …

Git: retroactively keeping tests green

I love using git bisect and git bisect run to know when things broke, but that only works if the commit history is generally clean - ie there are aren't commits with broken tests. The basic idea, given a failing test, and a test command (for the sake of illustration let's …

Rebuilding old DIY effects pedals

We'll see if this fares any better than my other neglected hobby projects, but I've started a page to track what I'm doing with three homemade effects pedals .

Stumbled onto an old Bitly blog post

I had forgotten that I wrote this 10 years ago while I worked at Bitly. Looks like the old Bitly tech blog isn't much maintained, but there's still some gems there: Getting more clues from Python’s logging module Not a bad little article. Nowadays we tend to rely more …

Recurse summer 2023 - part 2

I haven't posted much since starting at Recurse in July 2023 and extending my initial 6-week half-batch to a full 12 weeks. Here's a belated update on what I did in the second half! Godot beeps via ChucK ¶ First, I did experiment more with the "game" prototype that I started …

Modernizing my Python development setup in Emacs

Updated Feb 2024: Starting properly on MacOS; Completion demo; "peek" find demo. For some years, I've got by with a gradually evolving set of Emacs extensions and configuration to make me productive and happy while working with Python. I tend to be slow to adopt new tools once I've got …

At Recurse center! Part 1 ... And, blogging again!

Blogging again. A lot has happened in four years. One recent slice of it: I got laid off from Shopify in May 2023. It was an emotional gut-punch beyond what I could have imagined. If you've been through it, you know. One of the best things I did to pick …

Fun with recursion and The Little Schemer

The first thing I did at Recurse was spend a couple weeks trying to get comfortable with writing functionally and recursively in Scheme. One of the fun things about the book The Little Schemer is it has concise thought-provoking definitions. Like this one: How is a [natural] number defined? It …

Chai (bagged teas) reviews 2019-2023

Updated Dec 2023 . I love chai and I'm always looking for something that satisfies my cravings. So far I have only once tried hand-making my own chai spice mix, and it didn't turn out well... I'll let you know if I ever come up with something good! I don't drink …

Writing Tests that Fail Well

Writing better tests is a lifelong pursuit, apparently. One thing I've been noticing lately, especially while doing code reviews, is that we are usually thinking about how do I know the code worked . Great! But we are usually not thinking ahead about what am I going to do when the …

Sane project planning pt. II: Against Wishful Thinking

If you want to keep your customers happy, one foundation that your product process needs is a shared understanding across your entire organization around at what stage of development can you commit to a release date . When sales is involved, this also translates to: at what point can the sales …

Finding Which Superclass Provides a Method

Here's a quick hack to help when you're lost in a too-large Python inheritance tree. What class provides the most specific implementation of a method or attribute? def find ( cls , name ): for sup in cls . mro (): if name in sup . __dict__ : return sup . __name__ return None def find_all_vars ( cls ): for …

Thread Locals in Python: Mostly easy

Thread locals are an interesting idea: a way to give each thread its own storage, useful for global state that you don't want to share between threads. The obvious caveat is that threadlocals are still effectively global (for the current thread), and like all global state, should be treated with …

Celebrating Ten Years of Startup Orange

(Updated 2023/7/09) People sometimes ask me for career advice in software startups. For a long time I didn't know what to say. When I finally noticed a pattern in my career, it was like a blinding light. Now I know the single most important thing to advise: Make …

Thoughts on sane planning, part 1: Stagger your projects

TL;DR When scheduling features for a quarter, it's very risky to plan on delivering multiple projects that are starting from scratch. Let's call this the "Shiny New Quarter" approach to planning. Is this self-evidently problematic? Maybe to you. But apparently not to everyone, because I've seen it done repeatedly …

Cataracts? Really? Yes

I had cataract removal surgery this year. Twice: My left eye was done in May 2016, and my right eye in October. Since most people I know have no experience of this and are curious about it, I wrote up a description of the experience as a Q&A. Aren't …

git rebase is like nuclear power ...

It seems clean and safe 99% of the time. And then you have that one accident...

Finally, a blog

As a birthday present to myself, and a fit of fiddling while Rome burns, I have junked the ooooooold website, thrown out a bunch of cruft, and finally started that blog I never got around to. Most of it is geeky programming stuff, but with forays into music and other …

Prince: "When Doves Cry"

Shortly after Prince died, one of my favorite podcasts, "Switched On Pop", paid tribute to Prince by talking about one of his best-known and most distinctive singles, "When Doves Cry" . Weirdly, while this is a podcast that loves to talk about the parallels between music and lyrics, they barely mention …

Falsehoods Programmers Believe about REST APIs

In the spirit of "Falsehoods Programmers Believe" (my favorite is probably "Falsehoods Programmers Believe About Time" ), I offer this, about working with third-party REST APIs. "Believe" is a bit of a strong word here. Beliefs are deep things that are resistant to change. These are more like assumptions or wishes …

urllib2 gotcha

Does this return all the data? urllib2 . urlopen ( url ) . read () The answer appears to be "not always". https://stackoverflow.com/questions/7174927/when-does-socket-recvrecv-size-return https://github.com/CVL-dev/feedparser/issues/1 I can't seem to get a definitive answer here, nor a reproducible demonstration of it failing. Does anybody know for …

Fun with mocks, or: Mock-mock-unmock-unmock oops

In Python we often use the mock library to do dependency injection for tests. Recently I came across a really confounding edge case that can be easily avoided if you know about it. Mock intro redux ¶ (Skip this section if you're already familiar with mock .) Let's say we have a …

My Emacs setup [OUTDATED]

Some notes on my emacs setup circa 2015, mostly about Python. For the latest, see more recent posts tagged emacs and/or my emacs config repo Python ¶ Which mode? ¶ There is python-mode.el, and python.el. I have settled on python-mode from the elpa repositories. Why? The built-in python.el …

Using Sqlalchemy Declarative with Django and Nose, Oh My

So it turns out there are some painful edges if you start trying to do SQLAlchemy declarative ORM classes in an existing Django app. (For example, if you're gradually replacing the Django ORM in your code with Sqlalchemy ORM). It boils down to: The django testrunner (or django-nose) changes the …

Graphite, so confusing!

TL;DR graphite graphs look wrong when viewing a time period larger than a few hours. hitcount is the cure. It turns out counters are bucketed as hits per time slice, not as permanently incrementing numbers. https://code.hootsuite.com/accurate-counting-with-graphite-and-statsd/ helps a lot to explain how this works. For …

Python One-Liners: Generator expressions

Here's a typical loop that checks for some condition and breaks the first time it passes: def list_contains_urls ( maybe_urls ): for url in maybe_urls : if url . startswith ( 'http' ): return True return False Can we do that more concisely? Sure. def list_contains_urls ( maybe_urls ): return any ( u for u in maybe_urls if u …

convert hg repository to git

How to create a brand new git repository from an existing hg repository. This is not explained on https://hg-git.github.com/ easy_install hg-git # Now edit your ~/.hgrc as per https://hg-git.github.com/ # Now make a bare git repository. Yes, bare. git init --bare ~/my-git-repo # the --bare is important …

Linux on the Macbook Air (2013)

For various reasons that might be explained in more retroblogging , around January 2014 I got fed up with OSX and decided to switch back to Linux. I got things more or less working on my Macbook Air. (Later, in 2016, replaced with a Macbook Pro.) TL;DR: It's okay, and …

settings.py considered evil

Django's settings.py is evil. Why? Because in terms of security, it is a bomb waiting to go off. Typically your database settings go in there, and potentially other sensitive stuff (salts, service API keys, what have you). By encouraging you to put a settings.py file in your project's …

Python string split weirdness

Consider: >>> '' . split () [] That seems okay... split an empty string on whitespace and you get an empty list, sure, why not. Except that in every other case, if you split a string on a separator that it doesn't contain, you get a list containing the original string - even if the original …

Context Manager + Decorator

(Updated 2018 with a more modern Python 3 tip) I always forget how to write a class that can be used as both a decorator and a context manager. It's a handy trick, but I don't do it often enough to remember, so, here it is. In Python 3 it's …

map vs. iter

What's the difference between these? >>> zipped = zip ( iter1 , iter2 ) >>> mapped = map ( None , iter1 , iter2 ) The answer turns out to be depend on whether iter1 and iter2 are the same length. Pretty subtle: zipped is truncated to the length of the shortest of (iter1, iter2). mapped is the same length as …

pdbpp rocks!

A coworker (hi Will) just introduced me to pdbpp. As a longtime pdb user, I must say this is SOOO GOOD. Two features alone are worth it: syntax highlighting, and the ll command which prints the entire function around the current line. One wrinkle is that at work we still …

Git rebase conflicts

A couple of coworkers (Sean O'Connor, Dan Frank) bailed me out of a sticky git scenario. I'd been working on a branch for way too long and somebody else made wildly incompatible changes to a couple of the more important files I'd changed. When this happens, I'm prepared to accept …

Bash logging to both stdout and stderr

Somebody at work recently asked if it were possible in Bash to have stdout and stderr both visible on the terminal but also copied to separate log files. Normally when I think of console output and file logging at the same time, I think of "tee". But it can only …

Debugging as Immersive Game

Debugging with print statements is kind of like the old 2D Mario games. You get a little bit forward, learn a little more about the world you're exploring until something sends you back to the beginning. You get a little bit farther each time, but you keep having to go …

Django is not an application framework

Django as it is in the wild is not a web software framework. It is a web site framework. (disclaimer re. complaining: https://commandcenter.blogspot.com/2011/12/esmereldas-imagination.html ) What does this mean and why? For some things, I love Django. It hits a particular sweet spot really well …

Mock configuration tip

A little tip for working with the mock library. Let's say you need to set up some child attributes, like for example you're mocking up a django.contrib.auth.User , and you want it to be a logged in user: >>> user = mock . Mock () >>> user . username = 'Bob' >>> user . is_authenticated . return_value = True …