At work, one of the things I do pretty often is write print generators in HTML to recreate and replace forms that the company has traditionally done handwritten on paper or in Excel. This allows the company to move into new web-based tools where the form is autofilled by URL parameters from our database, while getting the same physical output everyone's familiar with.
This article explains some of the CSS basics that control how your webpages look when printed, and a couple of tips and tricks I've learned that might help you out.
Here are some sample page generators to establish some context, and perhaps a shred of credibility.
I'll be the first to admit these pages are a little bit ugly and could use more polish. But they get the job done and I'm still employed.
Coversheet with sidebar inputs
Coversheet with contenteditable
CSS has a rule called @page
that informs the browser of your website's printing preferences. Normally, I use
@page
{
size: Letter portrait;
margin: 0;
}
I will explain why I choose margin: 0
in the later section about margins. You should use Letter or A4 as appropriate for your relationship with the metric system.
Setting the size and margin of @page is not the same as setting the width, height, and margin of your <html>
or <body>
element. @page is beyond the DOM — it contains the DOM. On the web, your <html>
element is bounded by the edges of your screen, but when printing it is bounded by @page.
The settings controlled by @page more or less correspond to the settings you get in your browser's print dialog when you press Ctrl+P.
Here's a sample file I used to do some experiments:
<!DOCTYPE html>
<html>
<style>
@page
{
/* see below for each experiment */
}
html
{
width: 100%;
height: 100%;
background-color: lightblue;
/* grid by shunryu111 https://stackoverflow.com/a/32861765/5430534 */
background-size: 0.25in 0.25in;
background-image:
linear-gradient(to right, gray 1px, transparent 1px),
linear-gradient(to bottom, gray 1px, transparent 1px);
}
</style>
<body>
<h1>Sample text</h1>
<p>sample text</p>
</body>
</html>
Here's how that looks in the browser:
And here are the results of some different @page values:
@page { size: Letter portrait; margin: 1in; }
:
@page { size: Letter landscape; margin: 1in; }
:
@page { size: Letter landscape; margin: 0; }
:
Setting the @page size won't actually put that size of paper into your printer's feed tray. You'll have to do that part yourself.
Notice how when I set size
to A5, my printer stays on Letter, and the A5 size fits entirely within the Letter size which gives the appearance of a margin even though it's not coming from the margin
setting.
@page { size: A5 portrait; margin: 0; }
:
But if I tell the printer that I have actual A5 paper loaded, then it looks as expected.
From what I gather by experimentation, Chrome only follows the @page rule if you have Margin set to Default. As soon as you change Margin in the print dialog, your output is instead the product of your physical paper size and the chosen margin.
@page { size: A5 portrait; margin: 0; }
:
Even when you choose a @page size that fits fully within your physical paper, the margin
still matters. Here, I make a 5x5 square with no margin, and a 5x5 square with margin. The size of the <html>
element is bounded by the @page size and margin combined.
@page { size: 5in 5in; margin: 0; }
:
@page { size: 5in 5in; margin: 1in; }
:
I did all these tests not because I expect to print on A5 or 5x5 paper, but because it took me a while to figure out what exactly @page is. Now I am pretty confident in always using Letter with margin 0.
There is a media query called print
where you can write styles that only apply during printing. My generator pages often contain a header, some options, and some help text for the user that obviously shouldn't come out on the print, so this is where you add display:none
on those elements.
/* Normal styles that appear while you are preparing the document */
header
{
display: block;
}
@media print
{
/* Disappear when you are printing the document */
header
{
display: none;
}
}
You'll need to know a bit about the box model to get the margins you want without wrestling the computer too much.
The reason I always set @page margin: 0
is that I'd rather handle the margins on the DOM elements instead. When I tried to use @page margin: 0.5in
, I would often accidentally wind up with double-margins that squash the content smaller than I expected, and my one-page design spilled onto a second page.
If I wanted to use @page margin, then the actual page content would need to be laid out all the way up against the edges of the DOM, which is harder for me to think about and harder to preview before printing. It is mentally easier for me to remember that <html>
occupies the entire physical paper and my margins are within the DOM instead of beyond it.
@page
{
size: Letter portrait;
margin: 0;
}
html,
body
{
width: 8.5in;
height: 11in;
}
When it comes to multi-page print generators, you're going to want a separate DOM element representing each page. Since you can't have multiple <html>
or <body>
, you're going to need another element. I like <article>
. Even for single-page generators, you may as well always use an article.
Since each <article>
represents one page, I don't want any margins or padding on <html>
or <body>
. We're pushing the logic one step further — it is easier for me to let the article occupy the entire physical page and put my margins within it.
@page
{
size: Letter portrait;
margin: 0;
}
html,
body
{
margin: 0;
}
article
{
width: 8.5in;
height: 11in;
}
When I talk about adding margin within my article, I'm not using the margin
property, I'm using padding
. That's because margin
goes outside and around your element in the box model. If you use a margin
of 0.5in, you'll have to set the article to 7.5×10 so that the article plus 2×margin equals 8.5×11. And if you want to adjust that margin you'll have to adjust the other dimensions.
Instead, padding
goes on the inside of the element, so I can define the article to be 8.5×11 with 0.5in padding, and all the elements inside the article will stay on the page.
A lot of intuition about element dimensions is easier when you set box-sizing: border-box
. It makes it so that the outer dimensions of the article are locked in while you adjust the inner padding. This is my snippet:
html
{
box-sizing: border-box;
}
*, *:before, *:after
{
box-sizing: inherit;
}
Let's put this all together:
@page
{
size: Letter portrait;
margin: 0;
}
html
{
box-sizing: border-box;
}
*, *:before, *:after
{
box-sizing: inherit;
}
html,
body
{
margin: 0;
}
article
{
width: 8.5in;
height: 11in;
padding: 0.5in;
}
Once you've got your articles and margins set up, the space inside the article is yours to do with as you please. Design your document using whatever HTML/CSS you feel is appropriate for the project. Sometimes this means laying out elements with flex or grid because you've been given some leeway with the output. Sometimes it means creating squares of a specific size to fit on a certain brand of sticker paper. Sometimes it means absolutely positioning absolutely everything to the millimeter because the user needs to feed a special piece of pre-labeled paper through the printer to get your data on top of it, and you're not in control of that special paper.
I'm not here to give a tutorial on how to write HTML in general, so you'll need to be able to do that. All I can say is be mindful of that fact that you're dealing with the limited real estate of a piece of paper, unlike a browser window which can scroll and zoom to any length or scale. If your document will contain an arbitrary number of items, be ready to paginate by creating more <article>
.
A lot of the print generators I write contain tabular data, like an invoice full of line items. If your <table>
is large enough to go onto a second page, the browser will automatically duplicate the <thead>
at the top of each page.
<table>
<thead>
<tr>
<th>Sample text</th>
<th>Sample text</th>
</tr>
</thead>
<tbody>
<tr><td>0</td><td>0</td></tr>
<tr><td>1</td><td>1</td></tr>
<tr><td>2</td><td>4</td></tr>
...
</tbody>
</table>
That's great if you're just printing a <table>
with no frills, but in a lot of real scenarios it's not that simple. The document I'm recreating often has a letterhead on the top of each page, a footer on the bottom, and other custom elements that need to be explicitly repeated on each page. If you just print a single long table across pages, you don't have much ability to place other elements above, below, and around it on intermediate pages.
So, I generate the pages using javascript, splitting the table into several smaller ones. The general approach here is this:
<article>
elements as disposable and be ready to regenerate them at any time from objects in memory. All user input and configuration should take place in a separate header / options box, outside of the articles.new_page
that creates a new article element with the necessary repeating header/footer/etc.render_pages
that creates the articles from the base data, calling new_page
every time it fills up the previous one. I usually use offsetTop
to see when the content is getting far along the page, though you could definitely use smarter techniques to get the perfect fit on each page.render_pages
whenever the base data changes.function delete_articles()
{
for (const article of Array.from(document.getElementsByTagName("article")))
{
document.body.removeChild(article);
}
}
function new_page()
{
const article = document.createElement("article");
article.innerHTML = `
<header>...</header>
<table>...</table>
<footer>...</footer>
`;
document.body.append(article);
return article;
}
function render_pages()
{
delete_articles();
let page = new_page();
let tbody = page.query("table tbody");
for (const line_item of line_items)
{
// I usually pick this threshold by experimentation but you can probably
// do something more rigorously correct.
if (tbody.offsetTop + tbody.offsetParent.offsetTop > 900)
{
page = new_page();
tbody = page.query("table tbody");
}
const tr = document.createElement("tr");
tbody.append(tr);
// ...
}
}
It is usually good to include a "page X of Y" counter on your pages. Since the number of pages is not known until all pages are generated, I can't do this during the for loop. I call a function like this at the end:
function renumber_pages()
{
let pagenumber = 1;
const pages = document.getElementsByTagName("article");
for (const page of pages)
{
page.querySelector(".pagenumber").innerText = pagenumber;
page.querySelector(".totalpages").innerText = pages.length;
pagenumber += 1;
}
}
I've shown that the @page rule helps inform the browser's default print settings, but the user can override it if they want to. If you set @page to portrait mode and the user overrides it to landscape mode, your layout and pagination might look wrong, especially if you are hardcoding any page thresholds.
You can accommodate them by creating separate <style>
elements for portrait and landscape, and using javascript to switch between them. There might be a better way to do this, but at-rules like @page behave differently than normal CSS properties so I'm not sure. You should also save some variable that can help your render_pages
function do the right thing.
You could also stop hardcoding thresholds, but then I'd have to follow my own advice.
<select onchange="return page_orientation_onchange(event);">
<option selected>Portrait</option>
<option>Landscape</option>
</select>
<style id="style_portrait" media="all">
@page
{
size: Letter portrait;
margin: 0;
}
article
{
width: 8.5in;
height: 11in;
}
</style>
<style id="style_landscape" media="not all">
@page
{
size: Letter landscape;
margin: 0;
}
article
{
width: 11in;
height: 8.5in;
}
</style>
let print_orientation = "portrait";
function page_orientation_onchange(event)
{
print_orientation = event.target.value.toLocaleLowerCase();
if (print_orientation == "portrait")
{
document.getElementById("style_portrait").setAttribute("media", "all");
document.getElementById("style_landscape").setAttribute("media", "not all");
}
if (print_orientation == "landscape")
{
document.getElementById("style_landscape").setAttribute("media", "all");
document.getElementById("style_portrait").setAttribute("media", "not all");
}
render_printpages();
}
function render_printpages()
{
if (print_orientation == "portrait")
{
// ...
}
else
{
// ...
}
}
There are a couple of ways to get your data onto the page. Sometimes, I pack all of the data into the URL parameters, so the javascript just does const url_params = new URLSearchParams(window.location.search);
and then a bunch of url_params.get("title")
. This has some advantages:
This also has some disadvantages:
Sometimes I instead use javascript to fetch our database records over the API, so the URL parameters just contain the record's primary key and maybe a mode setting.
This has some advantages:
and disadvantages:
Sometimes I set contenteditable
on the articles so the user can make small changes before printing. I also like to use real, live checkbox inputs they can click before printing. These features add some convenience, but in most cases it would be wiser to make the user change the source record in the database first. Also, they limit your ability to treat the article elements as disposable.
<!DOCTYPE html>
<html>
<style>
@page
{
size: Letter portrait;
margin: 0;
}
html
{
box-sizing: border-box;
}
*, *:before, *:after
{
box-sizing: inherit;
}
html,
body
{
margin: 0;
background-color: lightblue;
}
header
{
background-color: white;
max-width: 8.5in;
margin: 8px auto;
padding: 8px;
}
article
{
background-color: white;
padding: 0.5in;
width: 8.5in;
height: 11in;
/* For centering the page on the screen during preparation */
margin: 8px auto;
}
@media print
{
html,
body
{
background-color: white !important;
}
body > header
{
display: none;
}
article
{
margin: 0 !important;
}
}
</style>
<body>
<header>
<p>Some help text to explain the purpose of this generator.</p>
<p><button onclick="return window.print();">Print</button></p>
</header>
<article>
<h1>Sample page 1</h1>
<p>sample text</p>
</article>
<article>
<h1>Sample page 2</h1>
<p>sample text</p>
</article>
</body>
</html>
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>[electronics] [today_i_did_this]
I have a Mediasonic Probox for file storage. After 3.5 years of use (purchased May 2020), one of the fans has gone bad:
The stock fans are labeled YLTC DFS802012H, 12 Volts, 0.23 Amps, and measure 80x80x20mm.
For my replacement, I chose the Arctic P8 because it seems to have a good reputation for being quiet, and I feel that a pressure-optimized fan (the P series) is more appropriate than a flow-optimized fan (the F series) for pushing air around the box's motherboard and between the drives.
Before doing some research, it hadn't occurred to me that the thicknesses of 80mm case fans wouldn't all be the same. On this Mediasonic forum post about fan replacement, someone commented that most fans on the market are 25mm thick and would not be a drop-in replacement for the 20mm stock. The screws are not long enough to go all the way through a 25mm fan, and the shroud, and have any real bite left over.
Besides the problem of length, there is also diameter: without the shroud, the screws slip straight through the mounting holes in the fan itself, so the shroud is necessary... or so I thought. Then I found this thingiverse thing where the author takes advantage of the empty space between the two faces of the fan housing to slip in a little hollow post. This bypasses the extra 5mm of fan thickness by placing the screw head within the Z-profile of the fan, and gives it something to grab onto, solving both problems at once! Very clever!
$fa = 0.1;
$fs = 0.1;
difference()
{
cylinder(d=5.5, h=10);
cylinder(d=2.9, h=10);
}
Please excuse the poor quality of the prints...
Also, most fans use a three-pin connector with one wire carrying RPM signal data, but the Mediasonic only uses the two power pins and a 2mm connector. There are adapters out there, mentioned in the forum post, so you can make the swap non-destructively. I was not in the mood to wait multiple weeks for aliexpress shipping, so I cut and soldered the ends.
Of course, you could just buy a fan that's 20mm thick with a two-pin connector in the first place. But all the options I saw were very cheap/generic looking, and the per-fan prices were not cheaper than the Arctics, and I've been wanting to replace the stock fans with quieter ones for a long time anyway. In this case, I'd rather buy a fan from a known brand with a good reputation for quiet, even if it requires some modification.
You have to admit this doesn't really seem like the ideal air path:
But the replacement went just fine and the fan feels very secure.
I felt I should add a bit of tape around the edge to discourage air from leaking into the sides, since the shroud is gone now.
After this, I also replaced the other fan in the same manner.
At low speed the new fans are essentially inaudible:
At full speed, they're still pretty quiet:
These recordings were made with no hard drives in the box. Once the drives are in... well... it's quieter than it was before but it's not exactly life-changing.
For the first few days, I heard a new sound that made me think the whole thing was pointless — it was a kind of ringing, or resonance, or beat frequency that was audible when I sat in my chair, but seemed to disappear when I got close to the box to listen for it. I'm not sure if it was an illusion, or the heart of my latest victim, or the bearings just breaking themselves in, but it's better now.
I don't normally publish this kind of thing, since I feel it's a little trivial or unimpressive, and because it mentions brand names. But whenever I am solving a problem, I rely on posts made by other people solving the same problem — something as simple as a hollow cylinder turned out to be a very helpful bit of inspiration to me. If that person thought a cylinder was too trivial to share, it would have taken me longer to do this. So maybe I should contribute back in the same way more often.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>The essential parts of a USB power bank are:
Artist's rendition:
But the majority of power banks on the market go the extra mile by adding a microcontroller that detects when the output current is low, and turns off the power bank.
The expected use case for these products is, first and foremost, to charge cell phones. I would love to be more broad and inclusive with that, but, no, it's mainly about cell phones. The phone will draw a high current while it is charging, and a low current when it is full, so the power bank detects that and shuts off.
This drives me crazy! These auto-off power banks make it impossible to:
A couple of quick searches will find you plenty of electronics hobbyists and DIYers who'd rather their power banks not turn off:
When I look at power banks for sale, the majority that I see have a single-button user interface, where pressing the button wakes up the power bank and displays the remaining charge level. Some brands, but not all, offer a low current mode that disables the auto-off feature, accessed by double-pressing the button, or holding it for a few seconds, etc. The joys of single-button UIs. This only takes effect for a single discharge session, and often comes with the caveat that it will still turn itself off after a few hours.
For power banks that don't offer a low current mode, the most commonly recommended solution is to put a resistor across the power bank's output. At 5 V, a 50 Ohm resistor will dissipate 100 mA, for example. That's right, the solution to your low-power project is simply to draw more power! Wow! Some more ambitious problem solvers will put the resistor on a timer so it draws a burst of current just often enough to keep the battery awake and minimize waste. But this still adds a clunky, intermediate dongle to your project.
Some of the very cheap power banks don't turn themselves off at all, and are valuable to the hobbyists. But they usually come from anonymous brands of no repute, which makes it impossible to provide a specific product recommendation because the brand won't exist in six months, and barely exists today. They typically don't even consider "always on" to be one of their selling points, so they don't mention it, which makes it nearly impossible to search a marketplace by keyword.
What I mean is, there are plenty of auto-off power banks that don't mention they are auto-off because it's considered standard behavior; and there are always-on power banks that don't mention they are always-on because it's not considered to be a selling point. The absence of either keyword practically means you have to assume it is auto-off.
One of the very, very few brands that prominently advertises their always-on power banks is Voltaic, and they charge a hefty price premium for what is, from this perspective, feature subtraction. The high price is accounted for by other perspectives: they're designed to charge from solar without browning out, they explicitly support charging while discharging, and they're aiming towards business clients purchasing in high volume. But that's not what I was looking for.
If you want an always-on battery, the most likely candidates are the $5 unit from a no-name whitelabeler that was too cheap to include the auto-off microcontroller, or the $50+ unit from the premium B2B IOT market, it seems. There are precious few in the middle, but they do exist, sometimes. I bought this unit via aliexpress for $19 and now that seller has gone bust, probably because they were falsely using Xiaomi's name or committing other scams. I was desperate.
So far, I haven't even talked about why power banks do the auto-off thing. I don't really know. It's probably because all the manufacturers are putting together building blocks from a small handful of suppliers and someone came up with it and now they're all the same.
Ostensibly it's to save power, and that's the answer people give. Are they referring to the output voltage regulator, drawing some current even when not in use? That's a good point, I wonder what else we can do to disconnect loads when they are not in use.
Artist's rendition:
I don't get it. Why do I see hundreds of power banks with the one-button interface, and none with a plain old on-off switch? Is that too 20th century? Even if you leave it switched on accidentally, it will still take weeks or months to self-discharge from the quiescent current. I know this because the always-on batteries I have sometimes go months without use. It's not the same as leaving a flashlight burning in your backpack.
The only other way I can think auto-off saves power is that the device being charged — remember, as a product designer you should anticipate it could be anything as long as it's a cell phone — will perform more background activity while it's plugged in. As I mentioned, Android will not enter Doze mode while it detects the charger, and I'd expect iOS to also use charging as an opportunity to do more syncing or network activity or whatever. So, specifically, I'm referring to a device that has reached full capacity and the user has not unplugged it from the power bank yet, so it's using a few extra milliwatts. And that's apparently worth discarding all other low-power use cases.
Some people will guess that the auto-off feature is to protect the power bank's own battery from overdischarge, but this is wrong. Low-voltage cutoff is done by the protection circuit which, ideally, is provided by a dedicated chip immediately in series with the battery. Auto-off also cannot be to protect the phone's battery, because the power bank cannot force the phone to take more power than it wants. Or else, mains-powered chargers would be popping everyone's phones.
A rant about batteries, of all things. I'm sure there are bigger problems out there. But this is simply one example of an annoying and pervasive trend in tech: solved problems becoming unsolved over time due to reduction in user control. Stuff used to be made with buttons and switches so I can decide what it does. Now it is made "smart" so it can decide what it does. A slight change in the product's design can improve the experience of one group of users with no downsides for the other. I am very tired of:
devices and appliances calling themselves smart devices, where the word "smart" means it does something you didn't ask for because the designers couldn't imagine more than one use case or mode of operation. I want you to do less!
devices that are non-configurable, non-customizable, and non-openable. I would be totally fine with a DIP switch on the inside of the unit, or soldering a jumper, if only you wouldn't use one-way plastic snaps in its construction!
single-button user interfaces, their multi-click and hold incantations, and internal state machines taking the place of simple physical toggle switches.
marketplaces flooded with thousands of whitelabeled copies of the same products, swamping out the few that are actually different.
feeling dismayed by our failure to do easy things.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>My camera lenses have white lettering printed and etched into the front describing their properties. I decided to paint over it.
Why:
I like stuff that is debadged or debranded and I think it will look cool.
I think / assume that the white lettering is distracting and catches attention, which is bad for candids.
I don't need my lens to remind me what it is. I'm the one who bought it.
I don't need my lens to tell everyone else what it is. If they care, they'll ask. If they don't, I'll spare them the advertisement.
I have no intention of ever selling them.
I used some matte black enamel paint and a 2mm round brush. I got the best results by picking up very light amounts of paint and dabbing it on. Any attempt to stroke the brush or speed up the process resulted in a horrible texture. I did a few coats on each lens. If you are a chemist accustomed to handling individual molecules of substance at a time, you might have more patience for this. It doesn't look factory-perfect, but I am satisfied with the look and texture I got in the end.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Over the past few weeks, I have been scanning my notes and homework from school using the nice professional scanners at my workplace. These notes have been sitting in my closet for several years because I don't want to keep them, but didn't want to throw them out until scanning them, and I've never had access to a scanner that could do all these pages.
This has prompted me to reflect on some of the habits and choices that I follow in my handwritten notes. I realize there are entire online cultures of journaling and notetaking and notebook-buying, and I'm not here to compete with them. This is just what I do.
Always put a date on every page, including pages that are given to you. For multiple pages in one day, it helps to add a page number.
Always use loose leaf paper, never bound notebooks.
Always use full-size paper (US Letter or A4 depending on your region) so that your notes stack well with printed material. A lot of lined/punched notebook paper is smaller than printer paper.
Prefer to write in black ink rather than colored ink or pencil. Use quality pens that produce deep black lines, not cheap pens that produce off-black or hollow lines.
Always write on a single side of the paper, never the backside, unless forced to do so. The dollar cost of the paper is less than the inconvenience cost of double sided material.
Resist the urge to cram everything onto one page. The telltale switch from big handwriting to "I'm running out of space" small handwriting at the bottom of the page is shameful. Two pages with healthy margins and spacing is better than one page of cramming.
Consider using graph paper, even for non-mathematics, non-engineering notes. Prefer faint gridlines. You can:
Consider using plain, blank printer paper. At work, I am currently using blank printer paper for notetaking, and my "manuscript" is up to about 140 sheets. I don't think I would recommend this for structured school lectures, but it's good for unstructured meetings.
As a result of writing this article, I have decided to try going back to graph paper for my work notes. This time, instead of using store-bought graph paper, I'm just printing my own. I created an svg file with a half-inch margin and a whisper-faint quarter-inch grid. This is working out great and I wish I had done it sooner.
Treat yourself to heavier paper stock. The cheapest printer paper is usually 20lb or 75gsm. Try something heavier like 28lb/105gsm or 32lb/120gsm. Heavier paper costs more, but it feels more pleasant to write on. If you enjoy it more, you'll do it more.
Consider re-writing your notes after your class/meeting, so that you can:
I have never used a digital tablet for notetaking, and I will not make the appeal to tradition that paper is always better. I can imagine it brings some advantages:
But paper has its own advantages:
I scanned everything at 600 PPI in 1-bit TIFF. The scanners at work don't seem to support lossless full color, and I'd rather have the aliasing and dithering artifacts of lossless 1-bit than the jpeggy, blocky artifacts of lossy color. This is an aesthetic preference and I think dithering looks cool anyway.
I wrote imagesequence_to_images.py to turn the scanner's multi-page TIF file into separate PNGs.
I use brename.py to rename everything.
When dealing with double-sided material and a single-sided scanner, I scanned the stack twice for the fronts and backs. Then, I did something like this:
md fronts && move fronts*.png fronts
md backs && move backs*.png backs
cd fronts
# Fronts will get even index numbers, starting from zero.
brename "f'{(index*2):03d}.png'"
cd ..\backs
# Large number minus index to reverse the file order.
brename "f'{(999-index):03d}.png'"
# Backs will get odd index numbers, starting from one.
brename "f'{(index*2)+1:03d}.png'"
cd ..
move fronts\* . && rmdir fronts
move backs\* . && rmdir backs
# ...
# Spend a few minutes manually deleting the blank backsides.
# ...
# Reindex all the files so we can pretend the blank backsides didn't exist.
# Renaming will fail if the target filename already exists, so temporarily
# bump up to more digits, then back down.
brename "f'{index1:04d}.png'"
brename "f'{index1:03d}.png'"
Here are some pages that I thought were visually interesting. These are not perfect demonstrations of the habits above, and that's the point — over time I have realized things I should have been doing all along.
I find there's something really engaging about being able to zoom in and pan around and pixel peep at these millimeter-sized features that, at the time of their making, only occupied a few tenths of a second of attention. The small writ large, as it were.
I am including more pages here than most anybody will care to look through, but I couldn't pick any more to eliminate. I think they're kind of cool.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Github has been bothering me. I don't like their drunk-on-buzzwords marketing copy or the advertisements they're placing above my work. If I give someone a link to my work, I want to feel proud of it.
So, I installed Gitea on my server and uploaded everything to git.voussoir.net. This was easy because I have no investment or dependency on github's issue tracker, project tracker, wiki, pages, CI, Actions, or whatever other proprietary lock-ins they offer. I will need to move some image assets eventually and that's about it.
I had tried Gogs at first, but it was failing on every push with a 502 error that I couldn't diagnose.
I followed Gitea's installation from binary instructions and updated my nginx settings. From start to finish, the process took maybe an hour and a half, which was a little longer than it should have been because gitea was trying to do some mkdir in /usr/local/bin/data/tmp
even though I asked it to use a different path. I had to manually set APP_DATA_PATH
in the .ini
file to make it stop doing that, and now it's fine. Even if I accidentally explode the whole server somehow, I can just reinstall gitea from scratch and push it back again. I still don't plan to use the issue tracker or whatever CI they come up with. I am deliberately calling it git.voussoir.net instead of gitea.voussoir.net in case I change the backing software.
...
Just a week after setting up Gitea, I learned that Gitea made a controversial move last year in forming a for-profit entity, and a new non-profit fork called Forgejo has started. I haven't personally being slighted. I just got here. But the words "non-profit" are like catnip to me so it looks like git.voussoir.net runs Forgejo now. Wow, my foresight paid off!
I won't delete my github account in the foreseeable future, because it's free and easy to keep pushing to all remotes. But github is losing my favor, and that's great for them too because I'm a nobody and I wasn't paying them anyway. So long, and thanks for all the fetch.
Note: If you want to keep it even simpler than this, git does have a web UI built in. See gitweb.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>[introspection] [life] [photography]
A conundrum. As usual. I must warn you this article is a self-contradictory stream of consciousness mess.
I was raised in the era where "don't share your real name online" was a standard rule. Pseudonymity practically paramount. I'm not old enough to have taken part in myspace, but I am old enough to have seen the rise of facebook and twitter.
In traditional web forums of the vBulletin and phpBB kind, and in online video games, it is customary to use a pseudonym and an avatar that is not a photo of yourself. Of course, the word "avatar" by definition means something that represents you but isn't literally you. Nowadays, websites don't ask for an avatar, but rather a "profile picture". They want names and faces, and plenty oblige.
When I say that the rule is "don't share your real name online", I don't just mean "don't connect it to your favorite pseudonym" or "make a separate profile with your real name". I mean don't share it at all. As in, you should always only use a pseudonym and there should be zero search results for your real name. That's difficult to guarantee, because any time you participate in a local club, competition, or event, there's a chance you'll be named in a roster or announcement that goes online. Where did I get this rule, anyway? I don't know. That's just how childhood programming works, I guess.
With a few exceptions, this is how I've lived my online life. It stresses me out when my name is published anywhere, especially linked to a physical place like a city or school, because it violates this rule that I have, thus far without enough question, taken as truth. If that doesn't sound stressful to you, perhaps you could imagine finding naked pictures of yourself shared online. If that still doesn't sound stressful, you must already be very popular.
But isn't it foolish for me to call y2k-era forum pseudonymity "traditional"? This is such an obvious bias on my part. People were posting on Usenet while the Berlin wall was coming down, which I was startled to learn. They wrote under their full names, and some even signed off with a postal address. I hope they don't mind that being copied around all these years later.
Anyway, as far as I can remember, this rule never came with a qualifier like "don't share your real name online until you're an adult" or anything like that. Maybe the rule is only for children and I just haven't grown out of it? Like, I was supposed to realize at some point that I no longer have to follow it? No, I'm sure that pseudonymity isn't just for children, or else doxxing wouldn't be considered such an aggression. I'm not the only one who perceives this rule as being generally applicable, and the use of real names as being a shameful symptom of eternal september:
Internet .1 - Finger protocol - Real Names, everyone pretty much knows each other (or the organization where you work) and is atmosphere is generally very friendly.
Internet .2 - Finger is no longer used, malicious users and hackers exist, social networks become very personal (Usenet, IRC) pseudonyms make sense, not just for privacy but to usher in a new sentiment of power and respect through anonymity. Computer security is very low.
Internet .3 - WWW becomes a thing, people still use pseudonyms and generally don't trust anything for good measure, computer security is very low.
Internet .4 - WWW evolves for the masses/commerce and social networks re-emerge on the web (Myspace, Facebook), people start to use real names everywhere. - A new generation exists that was never on the internet before .4. Computer security is much better.
Internet .5 - Pseudonyms don't become popular again thanks to the general ignorance of the tube watchers.
..not entirely accurate..just my 2C
When I got on the intertubes, oh-so-many years ago - the rules were simple: the ONLY piece of information you could freely give on public forums, or IRC, was your nick. Now, the only piece of information you are supposed to withhold is your credit card number.
I'll say this about the new ways: I'm extremely glad that I didn't have my teenage years documented and archived. Dodged that bullet!
Here I go again quoting HN users for general purpose life advice. Probably not the best idea.
I generally try to approach problems with a long-term perspective. I prefer things that are high-effort, long-lasting, and deliberate. That's one of the reasons I'd rather maintain my own website than play on any company's platform. The word "platform" is used so much these days it makes me sick. They spring up, screw people over for a while, then shut down. I'm not going to entrust them with anything I care about.
You could say that it's fine to have some real-name presence online: a boring, ordinary drone that blends in with the crowd; and to use pseudonyms to compartmentalize your hobbies, politics, and anything controversial. This is challenging because the more time you spend living in those pseudonyms, the larger a portion of your total life they become, and the more oppressive those compartment walls feel. If you do maintain perfect opsec, and keep your pseudonyms from ever touching, what do you have? A dozen identities, each a shallow dozenth of a person, and a dozen groups of peers that aren't allowed to mix? I don't think I want to invest such portions of my life into siloed identities, leaving my real name a boring husk of no consequence. I will only ever get to be one meatbag, at the end of the day. We like to treat the internet as if it's a separate place where you live a separate life, but it's not. This is your actual life.
When I first made my reddit account, I chose the name /u/GoldenSights instead of /u/voussoir because I specifically wanted to use a name that I wasn't using anywhere else. I assumed reddit would be a low-investment site that I would not want to connect back to my identity. But, through reddit's culture of bot programming (RIP) I discovered Python, and now I've been writing Python code for nine years. That's not the kind of time investment I want to keep hidden in a corner. If someone asks me what I've been up to for the past nine years, am I supposed to sheepishly say "uh, nothing, I can't tell you" so that I don't pwn myself? What a waste.
"Maintain perfect opsec". What kind of CIA espionage LARP am I on here? This sounds stupid. But really, there isn't that much middle ground. Either you allow your online names to lead back to your meatbag self, or you don't.
I gave up anonymity. I just learned to lean into taking control of my ID. Some time ago, I realized that there's no way for me to participate online, without things being attributed to me.
I learned this, by setting up a Disqus ID. I wanted to comment on a blog post, and started to set up an account.
After I started the process, it came back, with a list of random posts, from around the Internet (and some, very old), and said "Are these yours? If so, would you like to associate them with your account?"
I freaked. Many of them were outright troll comments (I was not always the haloed saint that you see before you) that I had sworn were done anonymously. They came from many different places (including DejaNews). I have no idea how Disqus found them.
Every single one of them was mine. Many, were ones that I had sworn were dead and buried in a deep grave in the mountains.
In fact, only two or three decades ago it was standard for the telephone service to print everyone's name, address, and phone number in a big book, distribute it to every house and charge you $5 a month extra if you wanted to opt out of the list.
In the past I've tracked down the names of people in old photo's with a viable house number by guessing the city and searching newspaper archives. Then confirm with a streetview. The archives will have articles mentioning people with their street address.
My thought is Americans have become really paranoid compared to people 50 years ago. And people are often under the illusion that people can find out a lot about you with little effort isn't true.
At the moment, my github page already shows my real name. That cat is out. I added that because as a computer science student there is a cultural expectation to use one's github profile as a public portfolio and to include it on resumes. I mean, once again, it would be really weird to say "I've been writing code as a hobby for this many years but I can't show it to you". I guess the pressure for employment was enough for me to break the rule. For a few years I had a linkedin account with a real photo, but I deleted that because linkedin is gross.
I am usually pretty good at resisting cultural expectations if I want to. I've never tasted alcohol, for example, and I don't swear. I never did use facebook or twitter or instagram or vine or tiktok. And while it'd be more noble to say that I am simply following my own beliefs and methods regardless of expectations, I know that I deliberately go out of my way to be contrarian. To not be a normie. But although I'm not harboring a secret desire to drink or to watch tiktok, and I am inwardly convinced of these choices, there's no doubt it is also very much an outward thing, a desire to be seen by others as the kind of person who does not follow the norm.
Sharing your real name and location online is different from following the other kinds of trends, though, because it involves crossing a significant point of no return. If I decide to try a drink, I can then decide to not have another one. I'd never be able to truthfully say I haven't tasted alcohol ever again — it would be a crossing in its own right — but it won't bring me any kind of future harm.
But once your name and location are public, you can't take it back. There is no return to anonymity. Is that important? Will that be a problem? Will it hurt me? Probably not. 99% chance not. But if it does, you can't go back. As long as you remain anonymous, you have unlimited time to ponder the consequences of deanonymizing; you can always delay that crossing. But once you are deanonymized, no amount of pondering can undo it. Are you sure you've thought it through? How sure?
The fearmongering that exists, or at least used to exist when I was young, about sharing your identity on the internet is that you'll get harassed by stalkers, molesters, and other crazies. Or, at least, scammers attempting identity theft or fraud or impersonation.
Wait... that doesn't make sense. Is that what this all comes down to? You've got to be kidding me. It seems like the vast majority of normies make their name, face, birthday, family ties, and whereabouts relatively public on social media, and the vast majority are not victims of death threats or fraud. It's not as rare as being struck by lightning, but if that's the entire scope of the threat then it doesn't seem worth the disproportionate worry about having my name online.
There are already billions of strangers' names on the internet. To me, I am very important, but to everybody else I am just one more stranger. It seems like knowing someone's home address is a big deal, but if you pan around on a map you've got thousands of people's home addresses right before your eyes. How meaningless. The fact that I write a blog makes me ever so slightly different from the norm, but the stuff I write is not nearly as inflammatory or unhinged as a whole lot of other stuff that's out there, available under the author's real name. I know the names, faces, birthdays, and/or hometowns of various filmmakers, actors, authors, athletes, musicians, CEOs, politicians, professors, and youtubers, and they're doing fine. Why would I not also be fine?
Horsley's website, created in 1997, listed roughly 200, as the website called them, "abortionists." These abortion providers were listed in three different fonts, as described by the site's legend: "Black font (working); Greyed-out Name (wounded); Strikethrough (fatality)." In addition to this list, the website included the abortion providers' personal information, such as their home addresses, phone numbers, and photographs.
The website, donned with blood-dripping graphics, both celebrated providers' deaths and, with a wink and a nod, encouraged others to harm the remaining providers on the list so that more names could be crossed off.
[...]
This fear is justified. Since 1993, eight abortion providers have been murdered because of their jobs. The most recent assassination was of Dr. George Tiller in 2009, shot while he was serving as an usher in his church. Several of the murders were preceded by Old West–style "wanted" posters that featured providers' personal information, a tactic still in use today.
Ok, so, there really are risks associated with deanonymizing. There are also risks associated with stepping outside and eating solid foods. I don't expect to be molested and murdered over my work, but it's... possible. While I was proofreading this article, Maddox released an hour long tale of stalking and harassment, and I guess I'll just keep telling myself it wouldn't happen to me because I'm not as inflammatory as he is. Or maybe I just shouldn't risk it. I have two choices: one carries a small chance of harm and the other carries none; so even if I can't actually justify the thought process, I may as well stay on the safe side.
Bang!
One of my assumptions has just burst. The assumption that remaining pseudonymous forever is not harmful. I am very lonely. Like, Joe Briefcase lonely. A lifetime of compartmentalization and self-imposed isolation between my real life and hobbies and work and creations and thoughts is taking its toll. My refusal to share my digital pseudonymous work with real-life coworkers / friends / acquaintances, and my refusal to make myself available for discovery / contact online is successfully preventing me from meeting like-minded people. There's more to it than that, but this isn't helping. I'm pretty certain that the expected value of this compartmentalized lifestyle is worse than a more public one.
Another reason to be more public is that if you don't define the web search results that come up for your name, you could be giving that privilege to someone else. If you ever do acquire some kind of enemy, and they publish your name and face with some message of hate, and they get to dominate the search results about you because you've kept all the good things about yourself a secret, that would kind of suck. Is this too contrived? Maybe.
This problem is on my mind because recently I have been attending some free outdoor concerts put on by the city as part of my effort to get out of the house more and curb my loneliness. I always bring my camera and take pictures and email them to the band as a way of giving something back. Plus it is useful and fun practice for me.
The reason this is a problem is because some of the pictures I've taken are actually really good, if you'll excuse the self-praise. I've got quite a few photos now that I think are pretty special, but you wouldn't know it because my /photography page is stagnating under the self-imposed pressure to not reveal who or where I am. In my hobby photography article, I already wrote that I'm not interested in taking meaningless eye candy pictures. Well, it turns out that meaningful pictures usually involve some quantity of recognizable people and places, at least for the genre and manner of photography I want to do.
So far, the responses I've gotten from the bands has been (presumably genuine) ecstatic appreciation. One of the guys I took pictures of last week was in the audience this week, and he and his wife approached me to say how grateful they were. As I said in my motivations for writing, visual arts can wow people in a way that my other hobby, computer programming, cannot. People actually want to share my photos on their website, and they want to credit me. "You can post the pictures but I prefer not to be credited" is so odd. Who do I think I am, some kind of Batman? Here I am sending an email to a musician whose email address I got from their website with their name and hometown and upcoming show dates, all public, and I'm playing Batman. My logic is completely incoherent. If I'm afraid of my work being known, maybe I don't deserve to do it in the first place.
Now that it's been a few weeks, I'm starting to learn the names of some of the also-regulars at these concerts. I've run into neighbors, coworkers, and even my dentist. Apparently one of the also-regulars goes to the same dentist. Is this what having a third place is like? People are beginning to ask questions:
Them:
Are you shooting for a newspaper?Me:
No, just for fun.Them:
Oh, what's your instagram?Me:
Sorry, I don't do instagram.Them:
Do you have a website where I can see your work?Me:
Ummmm... I was just gonna email the band directly.
I don't give them a link to my website, partly because I don't know if I want to build connections between voussoir.net and my real identity, and partly because I would look like a big idiot with my 'portfolio' full of anonymous closeups and abstracts, with none of the live band photos which I just told them I've been taking for the past four weeks. So instead I just look like a different kind of big idiot who takes five hundred pictures and apparently does almost nothing with them and awkwardly terminates the conversation at any mention of an outlet. Gotta go, bye!
I am not interested in making a new pseudonym and buying a new domain name for this purpose, either. Once again, I don't want to put years of investment into another identity that isn't me, leaving my actual identity empty and uninvested. Besides, all it takes is one person to share that domain in a facebook comment with "thanks to [my name] for taking pictures at our event" and it's blown anyway. May as well be ahead of it.
So, my real name is already tied to my website. That line has been crossed. But to publish these pictures would be to cross another line: tying my identity to a city. An environment for which I have already expressed some disdain. With named buildings in the background and the band's name on their banner or drum set, you could find exactly where I was... and where I'll be next week. That's pretty normal, but I don't like it. My other option is to let this body of work stagnate.
I've been using the word "portfolio", but I'll reiterate that this is absolutely not some kind of side-hustle for me. I want to publish these pictures on my website not to generate leads, but because I'm proud of them. I publish all of my Python code for fun, and I want to publish my pictures for fun, too. Also, because when I'm standing face-to-face with someone asking "Can I see more of your work?", I want to be able to say "Yes", instead of "No".
You're overthinking it!
Feedback wanted.
Update: I have not received any feedback, and I've taken some more good pictures. Scales tipped.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Patent Community Slams USPTO's Rush to Retire Software Systems
Apple slams Android as a 'massive tracking device' in internal slides
California Slams San Francisco for 'Egregious' Barriers to Housing Construction
NewsGuard and US Gov Sued by Consortium News; Musk Slams 'Scam'
FBI boss slams 'unprecedented' Chinese cyberespionage and IP theft
SpaceX slams regulators for Starship delay, risk of China beating US to the moon
Society of Authors slams 'lack of consultation' on Spotify audiobooks deals
Twitter pays thousands to account blasted for 'mocking' child's suicide
Israeli billionaire Idan Ofer quits Harvard's board, blasting the school
SpaceX slams FAA report on falling space debris danger
Pennsylvania University Slammed for Celebrating Nobel of Researcher It Demoted
Robin Williams' daughter Zelda slams AI for recreating her father's voice
'Get Help' - Elon Musk Blasted for Mocking Ukraine with Fake Zelensky Picture
Consciousness theory slammed as 'pseudoscience' - sparking uproar
China slams EU over electric vehicle subsidy probe
Taiwan blasts Elon Musk for calling the island 'an integral part of China'
Ancient-human fossils sent to space: researchers slam 'publicity stunt'
WGA Slams Studios' Latest Offer
Gump's Store Owner Slams SF in Open Letter Complaining About Street Conditions
Founder of Tech Giant Yandex Slams 'Barbaric' Invasion of Ukraine
LK-99 slammed as 'not a superconductor at all'
China slams Biden's order limiting U.S. overseas tech investment
Google Tries to Defend Its Web Environment Integrity Critics Slam It as Danger
US senator blasts Microsoft for "negligent cybersecurity practices"
Google's browser security plan slammed as dangerous, terrible, DRM for websites
Apple slammed with $1B class action lawsuit in UK over 30% App Store fee
Apple slams UK surveillance-bill proposals
Former NHTSA head blasts Cruise's 'Humans are terrible drivers' ad
Nobel Laureate Slams 'Climate Emergency' as "Dangerous Corruption of Science"
CEO slammed, replaces 90% of spport staff with AI chatbot, brags on Twitter
Privacy activists slam EU-US pact on data sharing
'It's pillage': thirsty Uruguayans blast Google's plan to exploit water supply
Oracle Slams IBM's Red Hat over RHEL Paywall
Winklevoss slams DCG's Silbert: Not even SBF was 'capable of such delusion'
GQ pulls article slamming Warner Bros. Discovery CEO Zaslav after complaint
Security researchers latest to blast UK's Online Safety Bill as encryption risk
James Cameron slams OceanGate safety, regrets not speaking up more
'Like Disneyland': Titanic Families Blast 'Disgusting' Tours of Wreckage
Warren Buffett, Bill Gates slam high-frequency trading (2014)
Reddit CEO slams protesters, calls them "landed gentry"
Music publishers sue Twitter, slam Musk for calling DMCA a "plague on humanity"
Health insurers slammed after UnitedHealth says more surgeries driving up costs
India Slams Jack Dorsey's Claim It Threatened to Shut Down Twitter
SF Transit Chief Blasts Cruise, Waymo Robotaxis as Unsafe: 'Race to the Bottom'
Climber rescued at Mount Everest slammed for thanking sponsors instead of Sherpa
Leaked MSFT messages show employees blasting pay cuts and low morale to execs
Elon Musk Slams People Who Work from Home: 'Laptop Class Living in La La Land'
Putin's unstoppable superweapon blasted by defense system
Hollywood writers, slamming 'gig economy,' go on strike
Judge slams Tesla for claiming Musk quotes captured on video may be deepfakes
Former federal officials slam WHO for misleading guidance on 'forever chemicals'
First look: RNC slams Biden in AI-generated ad
FSF Slams Google over Dropping JPEG-XL in Chrome
Arrest in Bob Lee killing silences critics who blasted San Francisco conditions
Jon Stewart blasts 'corruption' in Pentagon spending priorities
NPR CEO Slams Twitter for Labeling Its Account as 'State-Affiliated Media'
DPReview's Founder Blasts Amazon's CEO: 'What a Waste'
Lawmakers Blast TikTok's CEO for App's Ties to China, Escalating Tensions
Meta slams telco fee proposal, says ISPs should pay their own network costs
WHO blasts China for not disclosing potential data on Covid-19's origin
Lightning AI CEO slams OpenAI's GPT-4 paper as 'masquerading as research'
Microsoft's CEO slams voice assistants like Alexa
Arm Co-Founder Slams UK Tech Strategy Ahead of Firm's US IPO
Infosys founder slams working from home, side hustles, as slowing India's growth
GoDaddy Blasted for Breach Response
China Blasts US for Military, Cultural 'Hegemony' as Ties Sour
New York Magazine Blasts SF Techies' NYC 'Neighborhood'
Biden FCC nominee slams critics, says ISPs shouldn't get to choose regulators
Super Bowl Ad Slams Tesla's 'Full Self-Driving' Tech
Lawsuit blasts GoodRx, Meta over 'egregious' privacy practices
US Physician Blasts 'Lucrative System of For-Profit Medicine'
India's Adani slammed by $45B stock rout
Toxic exposure victims slam military, DOJ for delaying their pursuit of justice
Nelson Peltz lays out his case for Disney proxy fight, slams Fox acquisition
Days after layoffs, Salesforce CEO Benioff still blasts worker productivity
China blasts 'unacceptable' Covid curbs on travellers
Gemini's Cameron Winklevoss Slams Crypto Exec Barry Silbert over Frozen Funds
Tencent chief blasts managers in fiery townhall
Lawmakers slam Pfizer's 400% price hike on Covid shots
Coinbase CEO slams media for treating Sam Bankman-Fried with 'kid gloves'
Musk Slams San Francisco for Probe of Bedrooms at Twitter HQ
Spotify CEO Joins Elon Musk in Slamming App Store Policies
Facebook and Spotify CEOs Slam Apple's App Store
Email from Gregoire Nitot, CEO of Sii Polska, Blasting Employee for Unionizing
House Committees Slam ID.me for 'Baseless' Unemployment Fraud Claims
Red meat is not a health risk. New study slams years of shoddy research
New FTX chief slams 'complete failure of corporate controls' at crypto exchange
Wells Fargo, Zelle slammed by Liz Warren over rampant online banking fraud
NASA Puts Jet Propulsion Lab on Blast over Psyche Mission Failures
China's latest rocket debris crash blasted by NASA, ESA space chiefs
Three Arrows Capital Blasted an 80% Hole into the Biggest Loan Book in Crypto
Putin blasts West, says world faces most dangerous decade since WW2
Obama Said Some of What the Progressive Caucus Got Slammed for About Ukraine
Microsoft stock slammed by cloud-growth fears, taking Amazon down with it
Microsoft slams external researchers over its own data leak
The right-wing VIPs accidentally exposed in Parler's Kanye West blast
US election workers slammed with phishing, malware-stuffed emails
Horizon Worlds slammed in internal documents: 'An empty world is a sad world'
Metaverse getting slammed in internal documents: 'An empty world is a sad world'
Author coalition blasts publishers in legal fight with Internet Archive
Steve Wozniak slams Meta for yanking internship offers after Post report
Activision slams COD cheatmakers with racketeering charges
Jaishankar slams US deal to upgrade Pakistan's F-16s
Fiona makes landfall, slams Canada's Atlantic coast with severe winds and rain
Jamie Dimon Slams Crypto Tokens as 'Decentralized Ponzi Schemes'
Cryptocurrency collapse: Carnegie slams 'scumbag' crypto traders
Privacy groups slam plans for NYC subway cameras as 'surveillance theater'
GOP senators led by Graham slam Trump Jan. 6 pardon promise
Judge slams Musk for withholding text messages, cites "glaring" omissions
Judge Slams Musk for Not Handing over Texts in Twitter Fight
Braking news: Cops slammed for spamming Waze to slow drivers down
NordVPN Gets Slammed for Shadiness
Security researchers blast CrowdStrike bug disclosure practices
Apple workers launch petition slamming return-to-office mandate
Where have the unicorns gone? The IPO window has slammed shut
Marc Andreessen slams new multi-family affordable housing
Investors slam WeWork founder Adam Neumann's 'disgusting' comeback
Malcolm Gladwell slams working from home: 'What have you reduced your life to?'
Instagram rolling back changes after app slammed for being like TikTok
Elon Musk blasts Wikipedia after it suspends edits of 'recession' page
Two senators propose ban on data caps, blasting ISPs for "predatory" limits
Sanders Slams Corporate Giveaways in Microchip Legislation
Bill Gates blasts NFTs as 'greater fool theory', mocks Bored Ape Yacht Club
EU lawmakers slam "radical proposal" to let ISPs demand new fees from websites
Copyright Alliance blasts IA, warns "ruse" could also affect games and music
Bezos slams Biden's call for gas price cut
Kinzinger slams fellow Republican Boebert and warns of 'Christian Taliban'
China's blockchain boosters slam crypto as Ponzi scheme
Blackpink's Jisoo slammed for switching to iPhone after Samsung contract (2021)
Meta employees criticizing the rollback of perks are blasted as freeloaders
Bill Gates slams cryptos, NFTs as '100% based on greater fool theory'
SpaceX fires employees behind letter slamming Musk, tells staff: "Stay focused"
China blasts US 'bully', says it will 'fight to the end' for Taiwan
Amazon slams Amy Klobuchar's Big Tech bill while monopoly critics slam Amazon
"Amazon Is Full of Shit" Consumer Groups Slam Bezos' Antitrust Argument
Facebook Slammed for Spreading Putin's Propaganda in NATO's East
Musk Slams Biden: 'The real president is whoever controls the teleprompter'
Apple slammed by EU for denying Apple Pay rivals access to iPhone's NFC tech
Twitter employees slam 'a–hole' Elon Musk, ask whether he's manipulating stock
Uber Slammed over Pricing Surge After Brooklyn Subway Shooting
Startup Bolt's valuation tanks after founder slams Silicon Valley 'mob bosses'
Thiel Blasts Dimon, Buffett, and Fink as 'Finance Gerontocracy' at Bitcoin 2022
Bungie slams YouTube DMCA system in lawsuit against Destiny takedown fraudsters
Justice Thomas slams cancel culture, 'packing' Supreme Court
Stickers blast Biden at gas pumps
Uber, Ola Slammed by Bombay High Court for Operating Without Valid Licences
Ukraine Slams Moscow's Offer to Evacuate Civilians to Russia/Belarus as Immoral
Ambassador McFaul Slammed for "No Innocent Russians" Comments
Analysis: U.S. IPO slowdown slams door on tech unicorns looking to cash out
LA councilman blasts train theft 'chaos,' calls them 'a threat to our economy'
Gov't watchdog slams federal Covid response, puts HHS on "high risk" list
VMware Staff Blast Hire of AWS Manager Who Faced Probe
I-95 shutdown: Uber rider trapped in traffic slammed with $600 bill
Mozilla Founder Slams Mozilla Foundation for Adopting Cryptocurrency Payments
Competitors Slam Space Force's Hack-a-Sat CTF as Arbitrary, Unfair
Notre-Dame restoration slammed by critics as politically correct 'vandalism'
Ressa blasts U.S. tech titans for 'virus of lies' in Nobel Prize speech
Nobel Peace laureates blast tech giants and warn against rising authoritarianism
Pope blasts 'Nazi dictatorship' EU
Better.com CEO blasts laid-off employees, accusing them of 'stealing'
Extreme food prices slam inflation-ridden Turkey and Sri Lanka
Yoon slams government's nuclear phase-out scheme
'We are sick': Oil spill blasts Nigerian community
Reality Winner Blasts the Intercept After 4 Years in Jail
UC slams the door on standardized admissions tests, nixing any SAT alternative
Epic CEO Blasts Apple and Google, Calls for Single App Store
Pelosi slammed for attending lavish wedding maskless while children forced mask
Pelosi slammed for officiating lavish wedding of Getty oil heiress
Nancy Pelosi slammed as hypocrite for attending Ivy Getty's wedding maskless
Microsoft and Oracle slammed over 'anti-competitive' software practices
Edward Snowden Slams Sam Altman's Worldcoin: 'Don't Catalogue Eyeballs'
Windows ransomware gang moves earnings, others slam US after REvil takedown
In-N-Out blasts S.F. over shutdown: 'We refuse to become the vaccination police'
New Universal Force Tested by Blasting Neutrons Through Crystal
Infosec expert Beaumont slams Microsoft over hosting malware 'for years'
Netflix hit 'Squid Game' is so big North Korea is using it to slam South Korean
Summers Slams Woke Fed for Risking Losing Control of Inflation
Coinbase users slam new customer service phone support: 'It was a joke'
JPMorgan's Dimon blasts Bitcoin as 'worthless', due for regulation
Tim Sweeney blasts Apple for promoting its services ahead of developers on iOS
White House set to blast China
Senators Blast Facebook for Concealing Instagram's Risks to Kids
Google, in fight against record EU fine, slams regulators for ignoring Apple
Facebook slams Wall Street Journal reports as 'deliberate mischaracterisations'
China slams move by US and UK to help Australia build nuclear submarines
Tension over boosters rises FDA regulators quit and publicly blast Bidens plan
Amazon slams SpaceX, tells FCC that Musk-led companies are rule-breakers
School Blasted for Admissions Based on Students' Apartment Size in China
China blasts '996' excessive work culture
The People's Bank of China Blasts Bitcoin and Crypto. Once Again
Coinbase slammed for terrible customer service after hackers drain accounts
Hydrogen lobbyist quits, slams oil companies' "false claims" about blue hydrogen
Amazon employees blast the company's latest return-to-office plans internally
Top researcher slams Microsoft over 'astonishingly bad' security advisories
US media blast President for his 'blame-shifting'
Publishers Blast Internet Archive's Demand for 10 Years of Sales Data
Musk puts Renesas, Bosch on blast for Tesla's extreme supply chain limitations
Elon Musk slammed over SpaceX plan to put satellite ad billboard in space
Crypto community slams 'disastrous' new amendment to big infrastructure bill
Modern Pentathlon Format Slammed After Rogue Horses Make Farce of Event
SEC Chair Gary Gensler Slams Crypto as the 'Wild West'
World's Food Supplies Get Slammed by Drought, Floods and Frost
China's tech giants slammed for second day as Hang Seng dives
A thousand Activision Blizzard employees slam its response to harassment lawsuit
Sexual harassment lawsuit slams breaks on World of Warcraft development
Cloudflare slams AWS egress fees to convince to join discount data club
Biden blasts social media after Facebook stonewalls admin over vaccine misinfo
Intel slams US subsidies for TSMC in Arizona's clash of chip titans
Dogecoin Founder Slams Cryptocurrencies
Mexico, state-owned oil company slammed after subaquatic fireball
John Lewis slams UK education system and offers staff literacy lessons
mRNA technology pioneer blasts Big Tech censorship
Slamming political rivals may be the most effective way to go viral
India slams Twitter for not complying with new IT rules
North Korean defector slams 'woke' US schools
OSHA Slammed for No Food Plant Safety Mandate
Judge slams hospital staff for comparing Covid vaccine mandate to Nazi crimes
Op-eds in Chinese media slammed U.S. policy. The author works at The Pentagon
A "disgraceful decision:" Researchers blast FDA for approving Alzheimer's drug
Researchers blast FDA for approving Alzheimer's drug
Bangladesh blast western countries for $24b bank guarantee to Myanmar
Former Covid-19 Testing Czar Blasts Fauci for Lying About Pandemic Origins
France blasts 'pathetic' attempts to discredit Pfizer vaccine online
Consumer Reports Slams Tesla's Full-Self Driving Capability
Durov slams Apple for 'totalitarian' control and hardware from the 'Middle Ages'
Lauren Boebert Slams Joe Biden on Twitter, Users Return the Favor
Blind people, advocates slam company claiming to make websites ADA compliant
Ontario teachers' unions slam province for considering permanent online learning
Uni group slammed over submitting known buggy patches to Linux kernel
The folks behind Brave Browser slam Google for its new tracking policy
Brave browser chiefs slam Google's new experimental ad-targeting tech
Ousted Knotel founder slams new owners' "WeWork bros" hires
FDA slams "Real Water" linked to liver failure; water plant manager MIA
ProtonVPN CEO Blasts Apple for 'Aiding Tyrants' in Myanmar
DuckDuckGo Blasts Google over New iOS Privacy Labels
Federal investigators blast Tesla, call for stricter safety standards
ISP Industry Blasts UK Telecoms Security Bill
Google slams Microsoft for trying 'to break the way the open web works
FAA safety engineer goes public to slam agency's oversight of Boeing's 737 Max
Rishi Sunak slammed for ignoring IR35 as contractors face 'blanket bans'
Bill Gates Slams Bitcoin After Warren Buffett Praises Elon Musk and Tesla
Australia's government slams Facebook's move to block news content
WHO experts slam NYT for twisting, misquoting their words on virus origins probe
Antony Blinken blasts China in first phone call
GameStop: Cruz, Ocasio-Cortez blast Robinhood over trade freeze
Zuckerberg slams Apple in an earnings call, casting Facebook as a victim
Elon Musk blasts Jeff Bezos' Amazon, alleging effort to 'hamstring' SpaceX
California man blasts Texas 'dystopia' in Op-Ed after moving to Austin
Gemma Atkinson blasts 'lowest of the low' thieves who stole dog 'Makes me so angry!'
Google VP Vint Cerf slams Australia's media bargaining code
Trump admin slams China's Huawei, halting shipments from Intel, others
Vendors slammed for 'lack of proper judgement' during the pandemic
Comcast data cap blasted by lawmakers as it expands into 12 more states
Angela Merkel blasts Twitter's decision to permanently suspend Trump's account
Linus Torvalds slams ... himself over latest Linux build
Russian Opposition Leader Alexei Navalny, Blasts Twitter for Censoring Trump
Mexico president slams social media censorship
Lawmakers Blast Comcast's Pointless, Greedy Broadband Caps
Alphabet unit Wing blasts new U.S. drone ID rule, citing privacy
Biden team slams Twitter over plan to wipe followers from White House accounts
Facebook blasts Apple in new ads over iPhone privacy change
Facebook slams Apple's new privacy measures in full-page newspaper ads
Tom Cruise Blasts 'Mission: Impossible 7' Crew for Covid-19 Problems
Outgoing Facebookers Blast the Company
'Dune' Director Denis Villeneuve Blasts HBO Max Streaming Deal
Greta Thunberg Slammed over BMW Ad During Her Day as Editor-in-Chief
Whole Foods CEO blasts socialism: It's 'trickle-up poverty'
UK Environmental Audit Committee Slams Amazon and Apple
Apple Defends Delay of Privacy Feature, Slams Facebook
California Gov. Newsom's Thanksgiving Rules Blasted by Celebrities
Oatly Slams EU over 'dairy ban'
AT&T Blasts Pentagon Plan That Could Open Way for 5G Rivals
Facebook Slams Netflix's 'The Social Dilemma' as 'Distorted' and Sensationalist
Dilbert's Scott Adams blasts Trump's white supremacist answer: 'He screwed me'
Judge in Apple 'Fortnite' case slams Epic's tactics, hints at July trial date
Billionaire Jeffrey Gundlach slams California over taxes, may leave state
Elon Musk slams Microsoft exclusively licensing OpenAI's GPT-3
Senators slam bonuses for execs of bankrupt OxyContin maker Purdue Pharma
Ireland's data watchdog slammed for 'biggest breach of all time'
Ginsburg blasts Harvard Law (1993)
US Slams Visa Ban on Election Riggers in Nigeria
Bill Gates slams 'shocking' U.S. response to Covid-19 pandemic
Stanford expert blast Covid lockdown We quarantined the healthy exposed the sick
Facebook engineer quits, slamming stances on hateful and racist speech
Experts blasting proposed federal guidelines limiting alcohol to one serving/day
Facebook Employees Slam Zuckerberg over Militia Groups and QAnon After Kenosha
Berenson slams media for 'obscuring what the risks are' from coronavirus
Amazingly realistic Facebook ads slamming the company by a street artist in NYC
Elon Musk blasts SpaceX competitor ULA as 'a complete waste of taxpayer money
Top philanthropists slam Google for placing charity ads on disinformation sites
Millennials Slammed by Second Financial Crisis Fall Even Further Behind
Facebook slams Apple's App Store, launches Facebook Gaming without games
China slams 'dirty' America's 'clean network' plan, reminds world of PRISM
China slams President Trump's TikTok banned-or-be-bought plan in the US
Zuckerberg Goes Off-Script, Blasts Apple and Google in Testimony
TikTok blasts 'copycat' Facebook as US starts probe
Critics blast US study finding Alaskan mine poses little environmental risk
Bernie Sanders slams Tesla CEO Elon Musk over government stimulus package
Tim Sweeney of Epic Games Slams Apple, Calls It "Absolute Monopoly"
Bernie Sanders slams Elon Musk's opposition to stimulus package
Meatpackers Slammed by Covid Get Serious About Automation
Trump admin slams door on F-1 visa students attending online-only classes
Tech giants blast Trump executive order suspending H-1B visas
Proposed emergency preparedness rules for SMRs blasted as a 'radical departure'
Unions blast TVA for outsourcing IT jobs during pandemic
Popular Mechanics blasted for guide on 'how to topple a statue'
Apple Rejects Appeal of Email App That Blasted Store Rules
L.A. Congressman Slams Amazon's Use of Facial Recognition Technology
AFL-CIO blasts Facebook over software that could limit union drives
Lukashenko Slams Global Elites, They've Made 'Trillions' as World Economy Burns to Pandemic
FTC Slams Children's App Developer for Coppa Violations
Employees, civil rights groups blast Facebook inaction on Trump statements
Reddit slammed by former CEO Ellen Pao for 'amplifying' racism and hate
Civil rights leaders blast Facebook after meeting with Zuckerberg
Torvalds Blasts "Beyond Stupid" Flushing L1d on Context Switches
China blasts Trump over his response to US unrest
Zuckerberg slams Twitter as Trump plans to sign executive order on social media
US DoD Slams NYT Article Claiming Military Is 'Celebrating White Supremacy'
Whistleblower slams Apple for 'wiretapping entire populations'
Lancet editorial blasts Trump's 'inconsistent and incoherent' Covid-19 response
Vice Media CEO slams Big Tech as 'great threat to journalism' in layoffs memo
Scrabble fans slam 'sparkly abomination' new app
Texas courts slammed by ransomware attack
Sen. Blumenthal blasts Zoom for privacy while co-sponsoring anti-privacy bill
Watch: Trump blasts Covid-19 oversight committee: 'A bunch of Trump haters
U.S. Treasury blasts records with $3T borrowing need this quarter
Elon Musk slams "fascist" social distancing measures
Piglets aborted, chickens gassed as pandemic slams meat sector
Tyson Foods idles largest pork plant as virus slams industry
FCC blasted for "shameful" ruling against cities and fire department
U.S. envoy blasts Moscow's 'secret' trial of ex-marine charged with spying
4/20 fizzle: Pot industry tested as virus slams economy
Why Michael Savage Is Blasting Hannity and the Right-Wing Media on the Virus
Covid-19 Slams West's Nuke Carriers While China Signals Taiwan, Japan
Big Short investor who called subprime mortgage collapse slams Corona lockdowns
Micheal Burry of "The Big Short" slams Covid lockdowns in tweet storm
COBOL-coding volunteers sought as slammed mainframes slow NJ's Covid-19 response
Acting Navy Secretary blasts USS Roosevelt captain as 'too naive or too stupid'
Acting Navy Secretary Slams Fired Captain as 'Stupid'
Wisconsin farmers forced to dump milk as coronavirus slams fragile dairy economy
Covid-19:APC Chieftain, Adamu Garba Blast Buhari over Poor Handling Coronavirus
EU meltdown: Italy slams Merkel – Macron says coronavirus could end bloc
Prestigious medical journal slams UK response to Covid19
Mortgage Firms Brace for Wave of Missed Payments as Coronavirus Slams Homeowners
'A disaster': Airbnb hosts blast decision to refund guests amid coronavirus
John Oliver slams disney for censoring show against indian primeminister Modi
France recognises Uber driver's rights in blast to 'gig economy'
Blasting through Google Analytics for beginners
Court Slams Prager University for Its Silly Lawsuit Against YouTube
NTSB Blasts Tesla, CalTrans, and Nhtsa for Autopilot Death
Federal safety official slams Tesla, regulators for misuse of its Autopilot tech
Attorney General blasts tech, suggests companies be liable for dangerous content
Musk slammed one of Tesla's founders by calling him the worst
Taika Waititi Slams Apple's MacBook Keyboards After Winning Oscar
Huawei sues Verizon over patents; Verizon blasts 'PR stunt'
Clearview AI Slammed with New Lawsuit over Faceprint Sales
Altria stock slammed as Juul stake leads to another multi-billion charge
Did Forbes.com Get Slammed by Google in Organic Search?
Stadia owners on Reddit blasting Google over radio silence and lack of support
Former ACSC chief MacGibbon blasts calls to legitimise screen scrapers
Bloomberg blasts Warren, Sanders over breaking up big tech companies
Leave VGMA Matter For VGMA - Stonebwoy Blasts Rex Omar
Trump Slams Apple for Refusing to Unlock Suspected Shooter's iPhones
Google Ventures' Bill Maris Blasts Outgoing Chief Legal Officer David Drummond
Ben Horowitz slammed for slavery, prison comments at Pinterest
How Trump's Trade War Is Making Lobbyists Rich and Slamming Small Businesses
Impossible Foods CEO slams 'the most destructive technology on Earth by far'
Ring and Amazon get slammed with a federal lawsuit
China slammed over programme that 'appoints' men to sleep with Uighur women
Amazon slams 'improper pressure' from Trump in Jedi bid protest
FBI slams FaceApp as counterintelligence threat
TikTok Reverses Ban on Teen Who Slammed China's Muslim Crackdown
Papa John's Founder Slams Pizza After Eating 40 in 30 Days
Sacha Baron Cohen slams Facebook for allowing hate speech
AI hype opens doors as easily as it slams them in your face
Amnesty slams Facebook, Google over 'pervasive surveillance' business model
Uber Self-Driving Car Unit's Safety Culture Slammed by NTSB
Cyclists slam federal recommendation for state helmet laws
Goldman faces probe after entrepreneur slams Apple Card algorithm in tweets
Elizabeth Warren slams Twitter for policy banning ads fighting climate change
Ripple CEO Blasts Libra, Boasts of Warchest
Lawmakers Slam Apple for 'Censorship' of Apps at China's Behest
Blasting Boeing, FAA, safety panel recommends changes in certification process
Trump Slams Door Harder on Refugees
Transit app slams Lyft's attempts to 'take over mobility'
Google slams Aussie threat to 'directly intervene' on Android app defaults
Blast sparks fire at Russian laboratory housing smallpox virus
Female CEOs Blast Forbes List of Innovative Leaders That Includes Only One Woman
Sam Zell slams WeWork: 'Every single company in this space has gone broke'
Judge blasts "intentionally false" testimony by supposed Bitcoin creator
Walmart slams Tesla with a lawsuit claiming solar panels caught fire at 7 stores
Report Blasts Palantir for ICE Work, Trump Ties
AWS and Google slam Microsoft over cloud migration changes
UK cops blasted over 'disproportionate' slurp of years of data
Facebook's Libra Blasted in Congress
Donald Trump Blasts Bitcoin, Facebook's Libra in Twitter Tirade
Canadian ads blasted Hong Kong 'radicals', invoking blood loyalty to China
Antiviral Drugs Could Blast the Common Cold – Should We Use Them?
Wikipedia co-founder slams the 'appalling' internet
Nokia Slams Huawei After 'Potential Backdoors' Found in 55% of Its Devices
Facebook slams Apple as an 'exclusive club available only to aspirant consumers'
You're Huawei Off Base on This. Lawyers Slam US Senator Marco Rubio
Capt. "Sully" Sullenberger Slams Boeing for Inadequate Pilot Training
Alphabet employees blast policy on contractors and China at shareholder meeting
How Professors helped slam shut America's door
Jon Stewart blast Congress on behalf of 9/11 first responders
VC Slams Silicon Valley Heavyweights for Poaching London's Top Startup Talent
Google, WhatsApp, and Apple slam GCHQ proposal to snoop on encrypted chats
Judge Alsup Slams Patent Troll for Basically Everything
U.S. Doctors Blast Belgian Misinformation on Vegan Diets
Ex-NSA man slams Israel for strike on alleged Hamas cyber attackers
Infosec researchers slam ex-WaPO man Krebs over doxxing
Easy V-Slam on Raspberry Pi with Intel RealSense T265 Tracking Camera
R community blasts DataCamp response to exec's 'inappropriate behavior'
Carole Cadwalladr blasts tech titans at TED: Your technology is "a crime scene"
Huawei CEO calls Trump a 'great president' but slams his 'intimidating' tactics
Trump blasts New York Times reporting, says paper will be gone 'in 6 years'
Industry groups blast EU Parliament ahead of connected car vote
Europe slams 'exaggerated' US tariff threat and prepares to retaliate
Nerf Is Getting Blasted from Below
Writers Guild blasts plans by Endeavor for an IPO later this year
UK report blasts Huawei for network security incompetence
Intel Blasts Nvidia for 'Inferior' Self-Driving Technology
Intel's neuro guru slams deep learning: 'it's not learning'
EPA blasted for failing to set drinking water limits for 'forever chemicals'
Article 13 Negotiations Move Ahead, Artists Slam Labels for Disrespecting Them
MPs slam Android-only app for EU citizens to apply for settled UK status
What climate change? Davos bigwigs slammed for taking private jets
Researchers slam marine conservationist for touching great white shark
CA Governor Brown signs wildfire safety bill blasted as PG&E bailout (Sept 2018)
The Rock slams snowflakes as 'looking for reasons to be offended'
Unity blasts SpatialOS out of the cloud
MoviePass product manager resigned and blasted its leadership in email to staff
Scarlett Johansson slams deepfakes, says fake porn is unstoppable
Germany Slams Palestinian Mission for Glorifying Terrorist on Facebook
Angry California truck drivers are slamming new rule requires unpaid rest breaks
FCC slams spaceflight company with $900,000 fine
U.S., allies slam China for economic espionage, spies indicted
Researchers slam Hola VPN over absent encryption, user IP leaks
FCC Blasted for Opening the Door to Text Message Censorship
Doors are slamming shut for Huawei around the world
SoftBank slams the door on Chinese 5G investment
Senator blasts FTC for failing to crack down on Google's ad fraud problems
Judge slams bikini-app maker's lawyers in legal clash with Facebook
Scientists, ethicists slam decisions behind gene-edited twins
ESA team blasts Intel's new AI chip with radiation at CERN
Upended by frat boys: International lawmakers slam Facebook's effect on politics
IBM CEO Joins Apple in Blasting Data Use by Silicon Valley Firms
Facebook slammed for allowing South Sudanese user to auction off 16-yr-old bride
Singapore lawmaker blasts Facebook over refusal to take down 'false' post
Furious Traders Slam Crypto Exchange for Fiddling with Contracts
Key Israel minister slams Netanyahu, but won't quit government
Zuckerberg made his execs use Android after Apple slammed FB's privacy approach
Tech stocks are getting slammed, Dow tanks more than 500 points
Edward Snowden Slams Israeli Spyware Firm
Amazon exec slams HQ2 leaker: 'You're not doing Crystal City, VA any favors'
IT boss slams lazy Aussies who'd rather do paid work than do unpaid internships
'GDPR-US' needed, says Apple's Tim Cook as he blasts "data industrial complex"
Ex-Facebook exec slams Apple CEO's 'hypocrisy' over privacy
Tim Cook blasts 'weaponisation' of personal data and praises GDPR
Oracle Executive Chairman Larry Ellison Slams Amazon Over Cloud Security
DNS godfather blasts DNS over HTTPS adoption
Top climate scientist blasts UK's fracking plans as 'aping Trump'
'The Mother of All Scams': Roubini Slams Crypto in Senate Hearing
CA Governor Brown signs wildfire safety bill blasted as PG&E bailout
Steve Wozniak's online institute Woz U slammed with student complaints
Ajit Pai slams cities and towns as FCC erases $2B in local fees
Former Google scientist slams 'unethical' Chinese search project
GroupM slams Facebook, says it "doesn't operate with real-world metrics"
New artist slammed by bunch of feminist groups for this song
IRONY: Obama Slams Trump for Politicizing DOJ (VIDEO)
Google slammed for Chrome change that strips out 'www' from domains
Obamas speech slammed Trump's latter back I heard that I fell asleep
Coal miner puts GOP and Bob Murray on blast
Luxembourg blasts rate of corporation tax in Ireland – Irish Examiner
'Not a World Leader': Huawei Boss Slams Australia's National Broadband Network
Donald Trump slams Google search as 'rigged' even though it's not
Steve Jobs' widow blasts stepdaughter's memoir
Texas ISP slams music biz for trying to turn it into a 'copyright cop'
Doors Slam Shut for China Deals Around the World
OpenBSD chief Theo de Raadt slams Intel, says more CPU flaws likely to be found
Iowa Supreme Court Closes Warrant Loophole, Slams SCOTUS for Weakening 4th Amdt
Boris Johnson blasts London Mayor Khan virtue signals, young Londoners are dying
DuckDuckGo slams Google following EU antitrust decision
PG&E wildfire state bill blasted as bailout by some, deemed vital by others
Donald Trump slams EU over $5B Google fine
Facebook's Mark Zuckerberg Slammed by Germany Over Holocaust Comments
Google blasts Brussels after record €4.3bn Android fine
Keith Ellison slams hate group merchandise on Amazon in letter to Bezos
Netflix stock slammed after earnings, subscriber growth and revenue fall short
Former Tesla employee blasted by Elon Musk takes battle to SEC
Ethereum Creator Blasts Centralized Crypto Exchanges: "I Hope They Burn in Hell"
Trump slams Harley transfer business and say it will work with Harley competitor
Popular Mac Developer Slams Apple for 'Sad State of Macintosh Hardware'
Radio jet blasts seen as supermassive black hole rips star apart over 10 years
I slammed this milk company on social media. Here's how the CEO responded
Node.js Creator Blasts Node.js, Offers a Secure TypeScript-Based Alternative
Vint Cerf blasts techies for lackluster worldwide IPv6 adoption
Facebook slammed as a 'corporate dictatorship'
Pelosi slams Trump proceed to claw again Ebola money amid Congo outbreak
Emmanuel Macron slams Washington over lax tech rules
Making Change at Walmart blasts changes at annual meeting
Tesla CEO Elon Musk blasts media, pitches site to rate journalists
0 arrests, 2 correct matches, no criminals: London facial recog tech slammed
Net neutrality to die on June 11, as Ajit Pai blasts "special interests"
Boeing slams the Falcon Heavy rocket as "too small"
Tech giants hit by NSA spying slam encryption backdoors
Square shares go down moments after Citron Research slammed Bitcoin strategy
Boeing slams the Falcon Heavy rocket as "too small"
Hunt threatens new laws as he blasts social media 4 failing to protect children
NYC blasts broadband competition shortage as it pursues suit against Verizon
Tesla slams Reveal News after exposé on alleged factory improprieties
Experts Open Letter Slamming Europes Proposal to Recognize Robots as Persons
Trump orders Postal Service review after blasting Amazon deal
Slammed by Trump, Amazon's Jeff Bezos Chooses Silence
Zuckerberg slams Apple's Tim Cook's comments on Facebook as 'extremely glib'
Donald Trump slams Amazon for paying 'no taxes'
Trump blasts Amazon for hurting the postal service. Is that true?
Apple's Tim Cook slams Facebook: Privacy is a human right, it's a civil liberty
Quebec Blogger Slams Government to Detach on Cryptocurrency Mining
Monica Lewinsky blasts digital news: 'The more shame, the more clicks'
Flat Earth Rocketeer Finally Blasts Himself to Sky at God Knows What Speed
Snowden on Bitcoin: Blasts Public Ledger and Core Developers
Moscow slams UK 'Russophobia' and 'island mentality' over spy attack
Linus Torvalds slams CTS Labs over AMD vulnerability report
Elon Musk Slams Tesla Union Drive, Promises Workers Free Frozen Yogurt
Millionaire Slammed Over GoFundMe Campaign for Instagram-Famous Dog
Whole Foods suppliers slam 'hellacious' new policies
PayPal slammed after eBay snubs it for another payment partner
Uber CEO slams founders' 'pirate' culture, pledges to grow 'responsibly'
Mike Moritz slams politically correct tech culture, praises Chinese work ethic
Edward Snowden slams Indian govt over FIR against reporter on Aadhaar
iPhone X is slammed as racist by Chinese users
Senators blast DHS facial scanning at airports
Apple building store in Melbourne's Federation Square, residents slam tech giant
Mark Hamill slams light saber-wielding FCC chairman over net neutrality
Campaign to Drive Out Migrants Slams Beijing's Best and Brightest
Tom Wheeler slams Ajit Pai's plan to kill net neutrality rules
Randi Zuckerberg slams airline for letting passenger talk about touching himself
FCC Chairman blasts Twitter, Google for opposing net neutrality repeal
Judge Slams Uber for Withholding, Possibly Destroying Evidence in Waymo Trial
Snapchat founder Evan Spiegel blasts social media
Amazon staff blast 'intolerable' conditions
Russia slams Google over its plans to de-rank news from the country
Silicon Valley blasts Senate proposal to tax startup options
Sen. Al Franken Slams Facebook and Google's Control of the Press
Sessions blasts tech firms for blocking access to encrypted evidence
South Park slams Facebook for selling fake news
Critics Blast Mark Zuckerberg for 'magical' VR Tour of Puerto Rico Devastation
A GM exec slams Tesla's self-driving-car promises
Exiled Chinese billionaire blasts 'kleptocracy' running China
Judge blasts Waymo v. Uber lawyers, delays trial until December
Top Senator slams "inadequate" Twitter briefing
Spanish govt slammed over bizarre Catalan .cat internet registry cop raid
Google's AI Boss Blasts Musk's Scare Tactics on Machine Takeover
Jamie Dimon Slams Bitcoin as a 'Fraud'
Every Major Advertising Group Is Blasting Apple for Blocking Cookies in Safari
Linux gets blasted by BlueBorne too
NYPD's dep. commissioner of IT slammed a critic of Windows smartphone program
Big Sell Order Slams Gold Lower Before Jackson Hole
CloudFlare CEO blasts Anonymous claims of ISIS terrorist support (2015)
AMC slams MoviePass $10-a-month movie theatre subscription plan
Former Uber engineer slams Tesla 'We've got to start calling Elon on his sh-t'
Early Facebook and Google investor slams them for "aggressive brain hacking"
Google CEO Slams Memo on Gender as Employee Reportedly Fired
Google Grapples with Fallout After Employee Slams Diversity Efforts
Couple who slammed Dallas wedding photographer online, in media must pay $1.08M
Elon Musk Slams Mark Zuckerberg on Twitter Over the Safety of AI
Zuckerberg Slams Elon Musk on Superintelligent AI
Senator blasts FCC for refusing to provide DDoS analysis
Tesla slams IIHS after 'Acceptable' Model S test
Tim Cook blasts Trump's Paris accord move in email
Venture investors blast US decision to withdraw from Paris Climate Accord
Joe Biden blasted online echo chambers in a speech at Cornell University
Congressional candidate charged with assault after 'body-slamming' reporter
Microsoft slams US government on the 'ransomware' cyberattack
Microsoft president blasts NSA for its role in WannaCry attack
Italy's Beppe Grillo slams 'dummies' and 'slaves' after Macron win
Video Shows Palantir CEO Ridiculing Trump and Slamming His Immigration Rhetoric
Japan: 100-hour overtime cap slammed by critics as endorsing 'karoshi'
Tech advocacy group slams notion of SF income tax
Sir Tim Berners-Lee Slams UK and US Net Plans
Head of US military testing slams F-35, says it's unfit to fly
EPA tries to praise Trump's climate order, ends up slamming him instead
Putin Slams Geoengineering as Uneducated and Against Nature
How Ford has slammed the door on Silicon Valley's autonomous vehicles drive
MPs slam 'dismal' cost savings of government procurement body
JobsOhio slammed for how it runs state liquor business
McDonald's Tweet Blasts President Trump, and Is Quickly Deleted
Early Uber Investors Slam Travis Kalanick
Nobel Prize Winning Economist Blasts America's 'Rent-Seeking' Economy
Leaked Report Slams European Link Tax and Upload Filtering Plans
Uber investors blast company culture
Former Google Engineer Blasts Company's HR Practices After Sexual Harassment
Media slams limited WH press access
Uber investors blast company for failure to change: 'We have hit a dead end'
Tech coalition slams Homeland Securty proposal to collect social media passwords
Spotify slams 'ridiculous' deportation threat faced by staff in Sweden
CNN's Jake Tapper Blasts Milo's Defense of Men Having Sex with 13-Year-Old Boys:
Rand Paul Sides with Trump, Blasts McCain
UP Doesn't Need An Adopted Son: Priyanka Slams PM Modi, Priyanka Gandhi
Oracle CEO Mark Hurd Slams Amazon Cloud as 'old'
Jeff Berwick Slams Donald Trump for His Hypocrisy
Finland's Largest Trade Union Slams Basic Income as 'Useless'
Zenimax vs. Oculus: Carmack denies allegations, slams expert analysis
GCHQ cyber-chief slams security outfits peddling 'medieval witchcraft'
Reddit Bans Three Alt-Right Forums as Users Blast "Leftist Intolerance"
Trump Blasts 'Dumb Deal' on Refugees with Ally Australia After Tense Call
The month that killed the middle class: How October 1973 slammed America (2015)
Ivanka Slammed 4 Insensitive Gala Post Amid Protests Against Trump's Muslim Ban
Sundar Pichai slammed Trump's new executive order on immigration
Donald Trump Bodyslams, Beats and Shaves Vince McMahon at Wrestlemania
Facebook Slammed for 'Racially Biased Censorship'
Anthony Bourdain slams 'privileged' liberals
Black Lives Matter Slams Christmas, Links Holiday to White Supremacy
EU Court slams UK data retention surveillance regime
Tech CEOs get slammed ahead of meeting with Trump
SF blasts Uber, Lyft for downtown traffic congestion
Summers Slams Carrier Move as Threat to Capitalism
FCC Blasts Verizon, AT&T Over Net Neutrality: Why
'She f-k me for fame'-Ray J slams Kim Kardashian in new song 'Famous'
Steve Bannon blasted in letter by 685 Harvard Business School women
Facebook slammed for censoring burn victim's birthday photo
Sheriff blasted for sending drone to "track down some loose cattle"
Internet Pioneers Slam $750,000 Settlement for the 'Man Who Invented Email'
WordPress creator slams Wix: 'Your app editor is built with stolen code'
Many developers and creative pros are blasting Apple's new MacBook Pro
Ex-GM vice chair blasts Tesla, supporters 'like members of a religious cult'
Amazon Marketplace Shoppers Slam the Spam
Yahoo Slams Email Surveillance Story: Experts Demand Details
Squad devs blast Kerbal Space Program studio for high crunch and low pay
Samsung slammed by Chinese state TV over Note 7 recall 'discrimination'
After blasting the iPhone 7 the iPhone 8 super nice: Rimless / No Home key
Elon Musk's Mars colony vision slammed as elitist and evil
Microsoft CEO Satya Nadella slams Google's game-playing artificial brain
Facebook and Its Lawyers Slammed by Judge in Terrorism Suits
Tor slams FBI hacking powers extension
Facebook slammed for censoring iconic Vietnam War photo
Zuckerberg blasted for censorship of Pulitzer prize-winning photo
The Sun uses 'open source' software, then slams Corbyn for advocating it
Congressional Report Slams OPM on Data Breach
Indian judge slams ISP piracy warning for being deceptive
The Sun slams Corbyn for advocating 'open source' software
Vancouver's Housing Market Implodes, Furious Chinese Envoy Slams Real Estate Tax
Tech slams Homeland Security on social media screening
We're still blasting Tim Cook for no good reason
EFF blasts Microsoft over Windows 10 privacy concerns
Fernando Torres Blasts Liverpool, Reveal Reasons for His Exit
AdBlock Plus slams Facebook's latest update
Tech sector blasts IBM and ABS over [Australian] Census failure
Judge blasts FBI for bugging courthouse, throws out 200 hours of recordings
European privacy body slams shut backdoors everywhere
Edward Snowden Blasts Russia for DNC Hack
Driver involved in ModelX crash blasts Musk, claims Tesla drivers are 'lab rats'
Dallas police slammed for tweeting picture of 'suspect'
107 Nobel laureates sign letter blasting Greenpeace over GMOs
Sonia Sotomayor's Dissent Slamming Racial Profiling and Mass Imprisonment
NY Attorney General's Office Blasts Time Warner Cable Internet Service
Stop Chasing a Stock Market Return: Baby Boomers Prepare to Blast the Market
U.S. Shipping Industry Slams Amendment to Exempt Puerto Rico from the Jones Act
Artificial-Leaf Inventor Slams New Energy Finance, Blames Universities
Lawmakers Slam Frontier for Bad Internet, Phone Service
Oracle slams Google to jury: "You don't take people's property"
Obama Slams Parents Who Send Kids to Private School
Lead Plaintiff in Uber Class Action Suit Slams Settlement
Australian Productivity Commission Slams Protectionist Copyright and Patent Laws
World Jewish Congress Slams YouTube Over Neo-Nazi Videos
Indonesia's largest telco slams Netflix, calls it arrogant
Spotify Founders Blast Sweden's Business Environment in Open Letter
Spotify founders slam swedish business climate
Lipton slam live worms teabag claims what is REALLY inside lemon green brew
Newspapers slam ex-Mozilla CEO's new ad-blocking browser
'BLATANTLY ILLEGAL': 17 newspapers slam Brave ad-blocking browser
Mark Cuban blasts SEC for going after Silicon Valley's billion-dollar startups
Government report slams Theranos for quality control, unqualified personnel
Weev takes credit for anti semitic printer blast
What happens when AIPAC slams Trump's racism only to find out it was Netanyahu
Colleges slammed with lawsuits from men accused of sex crimes
Why Epic's Tim Sweeney blasted Microsoft in bid to keep Windows 10 open
Drug reform groups blast Silk Road founder Ross Ulbricht's life sentence
Art House Theaters Slam Screening Room, Say Startup Encourages Piracy
Wikipedia's Jimmy Wales blasts "deranged" companies editing their own pages
Kevin Smith and Ralph Garman Blast New Ghostbusters
Mitt Romney slams 'phony' Trump: He's playing 'the American public for suckers'
Samsung slams Apple in patent appeal decision
Facebook slams staff for defacing 'Black Lives Matter'
Apple Slams Order to Hack a Killer's iPhone, Inflaming Encryption Debate
UC Berkeley profs blast secret IT monitoring kit on campus
Martin Shkreli takes Fifth, blasts 'imbecile' lawmakers
Socat slams backdoor, sparks thrilling whodunit
Bill Clinton rape accuser blasts Hillary for presidential campaign
Google researcher blasts Trend Micro for massive Antivirus security hole
#OregonUnderAttack: People slam lack of govt action after militia takeover
Google slams AVG for exposing Chrome user data with "security" plugin
Jerry Lewis Unleashed: Slams Obama, Praises Trump…
Microsoft Slams Facebook's Free Basics Initiative in India
Apple Blasts UK 'Snooping' Bill
Business leaders slam 'luddite' Uber clampdown
Takei slams mayor over refugee stance
Free market is failing cyber-security, blasts GCHQ chief
Ex-employee blasts Twitter, rival firms come knocking
UN privacy head slams 'worse than scary' UK surveillance bill
GCHQ director blasts free market, says UK must be sovereign cryptographic nation
Hotel boss slams Airbnb for unfair taxes
DOJ indicts man who blasted false stock info on Twitter then traded on it
European Governments Slam Door on Data Transfer to U.S
Google slams the breaks on acquisition machine with lowest deal-making since 2009
EU Toughens Against TTIP as Top German Lawmaker Blasts Anti-Democratic Deal
FDA inspector slams Theranos for poor quality management
I slammed this company on social media. Here's how the CEO responded
Climate Change Slams Global Economy in a New Study from Stanford and Berkeley
Apple CEO Tim Cook blasts encryption backdoors
Apple's 'Move to iOS' app gets blasted with 2700 1-star reviews by Android users
Mozilla CEO blasts Microsoft for making it harder to keep previous settings
Mozilla CEO slams Microsoft over Windows 10 browser defaults
John Oliver blasts Americans for wasting tons of food
Uber's fake feature blasts NYC regulators
California tax officials blast Blue Shield in audit
Malicious app gets slammed by the FTC
IT pros blast Google over Android's refusal to play nice with IPv6
New York slams Verizon, calls city-wide FiOS rollout "an egregious failure"
Article Blasts Feds' Pseudoscientific Methods Establishing Dietary Guidelines
Hackers to Blast Apple Time Capsule, Fitbit and Samsung Baby Monitors at Defcon
Yahoo Stock Slammed by Potential Tax Threat to Alibaba Spinoff
Greenpeace blasts Amazon in latest cloud energy report, lauds Apple
Mozilla slams Facebook's Internet.org plan
Microsoft slams Android's update policy, announces 24x7 update plans for Win 10
FBI Slammed on Capitol Hill for 'Stupid' Ideas About Encryption
Top UK copper slams encryption
Super-Producer Bob Ezrin Slams State of Music Today
Researchers slam Telegram app's "visual fingerprint" security
FCC Slams AT&T with $25M Fine for Phone Customer Data Breaches
Sinch Blasts to $60M Run Rate in 10 Months
Google Blasts Media Implications That It Runs That Town
Caught on camera: ICANN CEO slams the internet's kingmakers
$1B TSA Behavioral Screening Program Slammed as Ineffective Junk Science
Internal audit slams DHS for canceling technology to fight bio-threats
Verizon and AT&T Slam FCC Net Neutrality Ruling
Eazyworld_zo slammed guy by his neck
T-Mobile CEO Slams AT&T, Verizon Spectrum Stranglehold
WikiLeaks Blasts Google for Quietly Handing Emails to the Government
WikiLeaks Slams Google Capitulation to US Government
Google Slams MPAA for Trying to Censor Internet: Project Goliath Reveals Rift
President Obama Slams Sony for Canceling "The Interview"
Singapore govt's Uber rival slammed as 'stunningly pointless'
Google slams Russia engineering office doors shut
Ron Conway blasts Sen. Feinstein's torture report
Mysterious 2008 Turkey Pipeline Blast Opened New Cyberwar Era
Mark Zuckerberg slams Tim Cook: If you cared, your products would be cheaper
Larry Page slams Silicon Valley, says it's not chasing big enough ideas
Facebook stock slammed: Paying price for its mobile success
Pope Francis blasts life sentences as a "hidden death penalty"
Scientific Community Blasts Microsoft for Closing of Silicon Valley Lab
FBI director blasts Apple and Google for offering encryption
FCC Slams AT&T with $105M Settlement for Bogus Customer Charges
Systemd Dev Slams FOSS Culture
Washington Post employees slam owner Jeff Bezos
Ello CEO Slams Facebook: 'An Ad Platform More Than a Social Network'
EU slams Apple's Irish tax deal
FBI chief slams Apple, Google for encrypting phones
FBI blasts Apple, Google for locking police out of phones
Patch Bash NOW: 'Shell Shock' bug blasts OS X, Linux systems wide open
World Wide Web inventor slams Internet fast lanes: 'It's bribery.'
Report slams Twitter, Facebook, YouTube for secrecy around harassment of women
Need more women? Salesforce blasts the gender imbalance in technology
Competitor slammed me in the press, said we couldn't scale. So I responded.
A founder I look up to (but now compete with) basically slammed my company
In 'Sherlock Holmes' Rights Dispute, Conan Doyle Estate Slammed Again
GCC Gets An Award From ACM and A Blast From Linus
Obama blasts US firms for 'magically becoming Irish'
Mark Cuban Blasts Companies That Jump Overseas To Duck Taxes
Apple slammed with another lawsuit in California over unpaid lunch breaks
U.S. Senator blasts Microsoft's H-1B push as it lays off 18,000 workers
EU slams US over Microsoft privacy case
4 Years Ago Evan Spiegel Left A Comment On TechCrunch And Got Slammed
Voters could slam S.F. house flippers with major tax
N.Korea's Kim blasts weather service for 'incorrect' forecasts
SpaceX's Musk slams USAF certification process
Fear mongering journalist pointlessly blasts WordPress
Users slam 'creepy' new feature that allows Facebook to listen in
Senate Slams Ad Servers for Security Failings
High Court slams HMRC for concealing information around export of spyware
Web Giants Slam Proposed Net Neutrality Rules
It's on: Google, Facebook, and more slam the FCC's plan for Internet fast lanes
New PayPal Exec Blasts Fellow Employees In Late-Night Tweets
Hillary Clinton Blasts Edward Snowden for Fleeing to Russia and China
After Eich resigns, conservatives slam Mozilla–and call for boycott
Greenpeace Blimp Buzzes Silicon Valley, Blasts AWS
Harvard Student Who Claims On-Campus Sexual Assault Slams University Policies
Netflix blasts Internet providers: 'Consumers deserve better'
EC slams Turkey for shutting down Twitter
Netflix CEO Slams Web Companies Over Net Neutrality
Brenda Romero blasts game industry culture of blaming sexual harassment victims
Netflix blasts Comcast and Verizon on net neutrality
Snowden: Feinstein a Hypocrite for Blasting CIA Spying
Zuckerberg-Linked Group Releases Ad Blasting House GOP For Immigration
Investor Icahn blasts eBay board, calls for company to spin off PayPal
Users blast LinkedIn for falsely implying that colleagues have accounts
Scientists Blast Plans for Nicaraguan Grand Canal
More arrests in Venezuela protests, Maduro slams "coup-seekers"
A mobile designer quit Apple and slammed the door loudly on the way out.
Journalist Deported From Turkey for Slamming Government on Twitter
"Fuck The EU" – US State Department Victoria Nuland Blasts Europe
Google and Cisco sign patent deal, blast 'patent privateering'
Analysts blast crappy Chromebooks reporting, defend platform's potential
AT&T's Sponsored Data slammed by lawmakers as a blatant shakedown
Israel slams reports of U.S. spying on prime minister
Task Force Blasts NSA's Collection and Storage of Personal Data
UK hosting firm slams open source cloud
Academia.edu slammed with takedown notices from Elsevier
Sir Tim Berners-Lee Blasts "Insidious, Chilling Effects" Of Online Surveillance
'Inferno' translator blasts Dan Brown's publishers
Google's Schmidt blasts NSA over fiber-optic snooping
Edward Snowden blasts U.S., UK as 'worst offenders' of criminal surveillance
Privacy groups blast Feinstein's NSA bill
Lawmakers blast patent trolls, but split on parts of a key bill
Head of NSA blasts reporters for 'selling' leaked documents
Samsung fined in Taiwan for hiring bloggers to slam HTC products
Media coverage for your company should be earned, not blasted
Microsoft's PR Boss Slams NYT Gadget Guru David Pogue After Infavorable Review
Mark Cuban wins insider trading case, slams government
David Byrne Slams Streaming Services
Taxpayer Subsidies Helped Tesla Motors, So Why Does Elon Musk Slam Them?
Anonymous RIM Employee Blasts Company in Open Letter (2011)
S is for small. iPhone 5s blasted in reviews for small display.
Why can't Microsoft slam Apple with style?
DOJ slams Apple's intransigence in price-fixing remedy discussions
Reporter goes rogue on RT, blasts "horrific" homophobia
Steve Jobs Movie Slammed by Critics — And Woz
Microsoft slams Gmail's 'Gspam' in latest Scroogled attack ad
Crypto experts blast German e-mail providers' "secure data storage" claim
Microsoft's Latest Scroogled Attack Slams Gmail's Email-like Ads
Android blasts iOS out of the water in Q2
Programmers slam Google for Chrome's 'insane password security'
Banker Bro Now Hiring Frat Dudes With Hot 'Slampieces'
NSA chief slams "transparency culture," compares Snowden to Boston Bombers
Thomas Yorke Slams Spotify Model - Pulls Catalogue
Putin Blasts US for Intimidation in Snowden Asylum Saga
Thom Yorke blasts Spotify on Twitter as he pulls his music
Top Scientist Slams Electric Vehicles, But Misses the Mark
'Hypocrite of the century': Irish MP blasts US president's G8 visit
Germany blasts Britain over GCHQ's secret cable trawl
European Publishers, Slam Google On "Abusive" Practices, Ask EC To Reject Google
Australian senators slam data retention plan
Alec Baldwin blasts government for cutting corners, trading freedom for security
'Progressive' phone company CREDO Mobile slams govt snooping, but can't stop it
US gov't defends NSA surveillance, slams 'reprehensible' journalists
US Spy Chief Slams Leaks on Surveillance Program
Intelligence Chief Blasts NSA Document Leaks
EFF blasts proposed DRM features in HTML5
Senators blast Apple for keeping most profits overseas in hearing
'Brave' creator blasts Disney for 'blatant sexism' in princess makeover
U.S. Senator Slams Use Of 3D Printer-Made Plastic Guns
EFF report slams Apple, Verizon, MySpace for not protecting users
Markets briefly hit by bogus tweet of White House blasts
Microsoft slams Google - Android Edition
Eighth grader designs standardized test that slams standardized tests
Reddit Is Getting Slammed by a DDoS - FBI Behind It?
WordPress Installs Getting Slammed w Password Guessing, Self-Propagaint Botnet
ICANN Slammed for Rolling Out gTLDs Too Quickly
European regulators blast Google for continued EU privacy violations
Bing's April Fools' Jokes Include A Slam On Google & A New SEO Tag
Man publicly tried to slam the Go programming language at FOSDEM 2013
EFF blasts plans to build DRM into HTML5
BlackBerry CEO Slams iPhone as No Longer Innovative
Parents, Experts Blast New State Database of Private Student Info
Apple's Schiller blasts Android, Samsung on Galaxy's eve
Book publishers blast Amazon's plan to control domain names
Linus Torvalds Blasts PC Industry, Praises Chromebook Pixel
U.S. CEO Blasts French Work Habits
West Virginia auditor blasts Cisco, state for "oversized" router buy
Google fixes 22 flaws in Chrome, slams silent add-ons
Fox blasts newest Dish Hopper in court, wants it off the market
Tesla's Elon Musk Slams New York Times review
Tesla CEO Blasts New York Times —Says Car Review Was 'Fake'
Microsoft blasts PC makers: It's Your fault Windows 8 crash landed
Triumphant motel owner slams Carmen Ortiz
Will Larry Page's Mobile Websites Slam Affect Google's Ad Policies?
GitHub unblocked in China after former Google head slams its censorship
Harvard professor blasts Web rumor of Neanderthal clone as "poor translation"
Sinn Fein slam 'short term internment' of Eirigi Newry spokesman Stephen Murney
Lawmakers slam DOJ prosecution of Swartz as 'ridiculous, absurd'
Microsoft has slammed the door on the Windows 8 Media Center activation flaw
Bing slams Google again, claims Google blurs the line between rankings and ads
McDonald slams Roads Service after Newry crash claims life
Brightcove CEO slams Facebook, wants end to "wars" over platforms
Vanishing 'copywrong' document blasts RIAA, suggests radical reform
HTC happy with Apple settlement, slams media estimates
UK start-up Luluvise slammed by Forbes
Twitter Completely Slams the Door on Tweetro; Refuses to Offer Exemption
Brightcove CEO slams Facebook, wants to end platform wars
SEC staffers slammed for serious security snafus
Apple blasts Samsung's post-trial "attack on the jury" as weak, unfounded
Lyrics site LiveUniverse slammed with $6.6 million copyright judgment
Lunch Lady slammed for serving food that is too good
Ad industry blasts Microsoft over Do Not Track defaults in IE 10
Homeland Security Blasted by Senate
Berlin Politician Slammed for Defending Copyright ("The Greedy Pirate")
Chicago Fed Study Blasts the Lid Off of High Frequency Trading
Apple Makes a Wrong Turn as Users Blast Map Switch
AT&T slammed over FaceTime block
Nokia slams HTC's Windows Phone 8 announcement, 'tactical re-branding'
Pentagon Slams 'Worst Ever' Contractor Lockheed Over F-35 Problems
Silicon Valley Guru Vinod Khosla Blasts Y Combinator
Bill Nye Blasts Todd Akin, Challenges 'Fucking Idiot' to Debate
Thank you, Bill Nye, for slamming creationism
Oracle Exec Slams Sun Hardware, Saying 'We Bought A Dog'
Citigroup slams Nasdaq's Facebook compensation plan
MIT Tech Review blasts ICANN / new top level domains.
Haarp horror continues with EMF blasts
Pippa Middleton slammed by designer Karl Lagerfeld
Video Slams "Political Prostitution" In Movie Piracy Cases
Nokia Slams Office Working On Qt Components
Kickstarter Projects Slammed with Success
OpenBSD's de Raadt slams Red Hat, Canonical over 'secure' boot
Judge blasts colleagues for defying Supreme Court, allowing financial patent
Copyright Troll Lawyer Slammed By Court of Appeals
Woz Slams the Feds on the Megaupload Case
Former Coke executive slams 'share of stomach' marketing campaign
Facebook Inc (FB) IPO: NYSE Blasts NASDAQ
Kim Dotcom lawyer blasts US government's "pattern of delay"
Analyst Slams Mark Zuckerberg For Wearing His Hoodie To IPO Meeting
Mozilla slams CISPA, says the bill "infringes on our privacy."
MTO ON BLAST: A language model for a gossip blog
White House Blasts CISPA, Promises Veto
The Band's Ex-Tour Manager and USC Professor Blasts Alexis Ohanian
York Butter Factory slammed over "sexist" tweet
Why isn't Abbott Labs getting slammed in the media for this?
Hotfile Slams MPAA's Interpretation of YouTube Ruling
Google Co-Founder Blasts Entertainment Industry On Piracy
Apple slams Amazon for behaving just like Apple
US slams Australia's on-shore cloud fixation
UK govt cloud chief blast federal CIOs, then retires
Carpathia blasts government for hypocrisy on Megaupload servers
California Slammed With Fukushima Radiation
Microsoft Slams Windows Exploit Code Disclosure
Apple Slammed Again Over Vulnerability Fix Process
UN official slams WikiLeaks suspect Manning's treatment
Torvalds blasts openSUSE, security policies
Advisory Service Slams Facebook's Dual-Class Share Scheme
Critics slam SSL authority for minting certificate for impersonating sites
Paramount "humbled" by SOPA protests even as CEO blasts "mob mentality"
IFixit blasts Apple for tiny torx screws
Microsoft Slams Google Privacy Changes With "Putting People First" Ad Campaign
Ushahidi Slams Twitter for Censorship
BugFinders slams poor ecommerce testing
AT&T CEO Blasts FCC, Hints At Higher Prices & Data Restrictions
Eight Months After Sen. Schumer Blasted Bitcoin, Silk Road Still Booming
Judge blasts "unlawful invasions of privacy" by "rogue" P2P attorney
Strongly pro-IP attorney blasts Supreme Court for re-copyright ruling
MPAA blasts 'dangerous' anti-SOPA blackouts as 'stunts'
Woz praises Android, blasts iPhone limitations
Twitter boss slams Wikipedia's 'silly' Sopa protest
Rupert Murdoch uses the Twitter to blast Obama on SOPA, issue cry for help
Murdoch slams White House over SOPA in Twitter row
White House Blasts Internet Blacklisting Bills
Twitter Slams Google: Social Search Changes Are 'Bad for People'
Kasey Kahne apologizes for slam
RIAA Slams Google's Anti-Piracy Efforts, Demands Even More Unreasonable Measures
Google-funded security report slams Firefox
Silicon Valley execs blast SOPA in open letter
Nvidia slams Intel: says ARM supercomputer to be more efficient
DHS Blasts Reports of Illinois Water Station Hack
Britain's chief rabbi blasts Steve Jobs, Apple (then says he didn't)
GAO Blasts IRS Over IT Security Weaknesses
10gen's response to MongoDB's slams
U.S. report blasts China, Russia for cybercrime
MIT Media Lab pumpkin-blasting laser carves jack-o'-lantern
Robert Zubrin - Obama Readies to Blast NASA
Jurgen Klinsmann's PowerPoint expenses slammed
Google engineer slams Amazon and Google+… on Google+
Can Federer win another slam? How can he do it?
Kevin Mitnick's autobiography slammed by security researcher
Judge blasts personal-injury lawyer for running P2P "shake down"
Joe Hewitt, renowned Facebook and Firefox developer, slams the 'open web'
Congressmen blast "supercookies" as privacy menace
Two mobile trends slamming against retail
Council blasts shared services in favour of localisation
Editor who published controversial climate paper resigns, blasts media
US regulator slammed with catastrophic allegations of widespread data wiping
VC John Backus blasts Vivek Wadhwa's "5 Myths About Entrepreneurs"
Mozilla (Carefully) Slams Apple
Google Researcher Exposes Flaws In Sophos Software, Slams Antivirus Industry
Federal Circuit Slams Patent Troll
Australian app developer slams Amazon over free deal
BT slammed over 'ridiculous' NHS value for money claim
China Blasts US On Debt Ceiling
Judge blasts Google and Oracle for their damages estimates in a patent dispute
Google's Eric Schmidt slams Apple iPhone lawsuits
Chinese Censorship Gets Blasted by New Satellite
Open letter from anonymous RIM official blasting company surfaces online
Sarah Palin Blasts Hollywood Stars as 'Full of Hate' at Movie Premiere
High tech investors slam Hollywood, blast Internet censorship bill
Conan O'Brien Slams Final Cut Pro X
Kindle E-Book store slammed by spam "authors"
Fed judge orders ISP to release names of online commenters who slammed retailer
Berlusconi slams leftist communist dictator-like-ist magistrates again
Google Apps for Business: Limit Free Users, Slammed by Microsoft
House hearing blasts Sony's "half-hearted, half-baked" hack response
Madoff judge slams 'sloppy' US regulator's failure to use case management system
Directors slam $30 early release home video offer
Video-on-Demand Startup Zediva Gets Slammed by the MPAA
FCC Commissioner slams N. Carolina attack on city-owned broadband
Microsoft Slams Google With Antitrust Complaint
Color App Is Universally Slammed, Especially By One Reviewer
Activists slam Go Daddy CEO for elephant hunt
Mac Genius Slams His Google Job
Hotz fires a powerful blast back at Sony's California jurisdictional claims
When Steve Jobs put former Disney CEO Michael Eisner on blast
Angry Birds Slammed With 1-Star Ratings After Adding Ads to Paid App
After some tweaking, Air Force set to blast second hypersonic jet
Jon Bon Jovi slams Steve Jobs for 'killing' music - MSN Music News
Chernobyl clean-up expert slams Japan, IAEA
Bon Jovi slams Jobs for 'killing' music
AMD blasts Apple's Thunderbolt technology
Ouch: Consumer Reports slams the Verizon iPhone 4
Amazon's subtle slam of the iPad
Rhapsody blasts Apple's 30% cut, but says it can live with Google's 10 %
Backers drown out jeers as Ron Paul slams Patriot Act at CPAC
WikiLeaks Defector Slams Assange In Tell-All Book
Vodafone slams Egypt PM Mubarak over text 'hijacking'
Quora Backlash Slams Head First Into Quora Backlash Backlash
Pirate Party slams police over Anonymous arrests
Governor Ventura slams TSA with lawsuit
G2 Fuel Brings Bio-Blast for Industrial Use
Gartner slams Cisco's single-vendor network vision
Microsoft Evangelist Brilliantly Slams Google's Decision To Drop H.264 Support
MP slams possible court order to Google as 'waste of money'
Adioso (YC W09) Slams Bing, Says They Don't Have True Natural Flight Search
Author Slams eBook Piracy, Son Outs Her As a Music Pirate
WikiLeaks slams Amazon over dumping
RIAA Blasts PCMag.com Over Limewire Article — Get Real
The Federal Reserve Just Slammed Savers, And Gave A Huge Gift To The Banks
Apple "Slams" Motorola With Multitouch Lawsuit
British Airways Chief Slams US Security Requests
Pilot who refused body scan at Memphis International blasts TSA security
RIM CEO Slams Apple 'Distortion Field'
WikiLeaks founder Julian Assange slams Wired magazine on Twitter
Steve Jobs slams Google, RIM, and rival tablet makers on conference call
Australia's largest telco slams Apple's "walled garden"
FTC slams shut telephone cramming scam
Twitter Boosts Marketer Reach With Plan to Blast Promoted Ads
Computer Genius Slams Oracle CEO: 'Gives Me the Creeps'
Hunters Blast Google Aerial Fiber Cables
Microsoft Exec Slams Android, Outlines Windows Phone 7 Strategy
Yahoo CEO Carol Bartz slams Apple's iAd "That's going to fall apart for them"
Pentagon Slams WikiLeaks' Plan to Post More War Logs
Oracle's Ellison blasts HP board for Hurd's exit
No Jacket Required - Motorola Buys Full-Page Slam Ad Against Apple
Navigenics, 23andMe slammed in government report
Microsoft exec slams iPhone 4 by comparing it to Windows Vista
CNBCs Mark Haines Slams Factless Guest
Video: Conroy re-commits to filter, slams opt-out amendments
Oil Execs In London Slam Obama's Drilling Ban
Snowe, Enzi Blast S-Corp Provision in Tax Extenders Bill
Google Blasts Apple's New iPhone Advertising Terms
Mozilla man blasts Apple and Google for HTML5 abuse
Guy Who Copied Digg Slams Digg For Copying Twitter
Free speech not protected for gripe site owner blasting former firm
Church of Scientology blasts Russian government for L. Ron Hubbard ban
WEST COAST LATIN INDIE LABEL BLASTS LATIN GRAMMYS
IiNet, Pirate Party slam AFACT political moves
Stallman Slams UK Broadband Proposal
IControlPad developer slams Apple gaming peripheral patent application
Delaying Kindle Release Leads to Amazon Review Slams
Chinese media slam Google as 'politicized'
Google Street View slammed as 'a service for burglars'
Facebook, Google and eBay slam Digital Economy Bill
Kwedit Gets Slammed On Colbert, But Raises $3.3 Million To Soften The Blow
Whirlpool founder slams Australia's Internet filter
Beijing blasts Google claims as 'groundless'
FastCompany slams me for "how to get press" posting (in a lighthearted way)
China Slams US Criticism of Internet Controls
China slams U.S. "information hegemony"
Tsutomu Yamaguchi, Survivor of 2 Atomic Blasts, Dies at 93
FCC Commissioner slams Verizon on $350 ETFs
Simon & Schuster CEO slams "cheap" digital books
Google slams proposed Australian Internet filter
UK Government slams critical database report (Anderson et al., 2009)
Facebook Slams Twitter: FarmVille is Bigger Than You
French court slams eBay with €1.7M fine over LVMH product resale dispute
Man U's Neville blasts millionaire players for wasting money on agents
Google Chrome OS slammed by Microsoft, Linux vendors
Facebook, MySpace, slammed for not introducing 'help button to protect kids'
Slamming Amazon over sales tax collection fight with states
Kim Stanley Robinson slams Republican climate change 'denial'
Australia's Pirate Party slams secret copyright talks
Andy Ihnatko slams Verizon's iDon't campaign
Penelope talks miscarriage–gets slammed, Pulver talks penis–gets patted on back
Kim Stanley Robinson slams Booker Prize judges' sci-fi ignorance
Huawei slams China spy claims in Australia
Employee reviews on Glassdoor.com slam Cisco
Sci-fi author Charles Stross slams US politics
D.C. Circuit Slams IRS: Calls tactic "aggressive, creative, inventive and mean"
Chris Ahearn, Thomson Reuters: Slams AP Link Policy
Richard Marx Blasts Verdict And Apologizes to Jammie Thomas
German Court Slams Rapidshare With $34 Million Fine
Angry iPhone owners blast AT&T
Obama defiant on Guantanamo closure, slams Bush 'mess'
Mozilla, Opera blast Microsoft over IE8 upgrade practice
China fears bond crisis as it slams quantitative easing
AOL plan to build ad sales slammed by 20% Q1 revenue drop
Sun's Open-source Boss Slams App Engine's Java Support
Courtney Love redefines music piracy and blasts the RIAA
Dear Huffington Post: Please, stop using "slams" for everything
Phishing Slamming into Twitter
Huffington Post blasted for stealing content
The Huffington Post Slammed for Content Theft
Rare 50 year Arctic Blast Sets Sights On Southern California
Ballmer slams door on Yahoo deal
Ex-president Carter slams Bush on market crisis
O'Reilly Blasts Barney Frank On Fannie Mae Mess
Novell Engineer Blasts Ubuntu for not Helping Linux
Larry Page blasts white space FUD on capitol hill
The Register slams OpenSocial, OpenID and Google Gears - "destined for the dustbin"
Pope blasts Internet and violent video games
Ford Sales Slammed By High Gas Prices
PayPal upgrade chaos prompts StatCounter to publicly slam the service
SlideShare Slammed with DDOS Attacks from China
Mozilla CEO Blasts Apple's Safari Ploy
Physicists slam publishers over Wikipedia ban
OpenSolaris' Fielding leaves developer community, slams Sun
IBM Slams Microsoft, Calls OOXML "Inferior"
Database gurus slammed for Google post
Dreamhost slams Rails for not working well on shared hosting
PayPerPost Bloggers Get Slammed By Google
Scoble slams Google Android: we want developers but...
Lawmakers blast Yahoo executives for helping China jail dissident
Web, AJAX slammed for deficiencies - JSON founder slams: security holes, difficult programming
DiveIntoMark slams "Project Zero"
Watchdog Group Slams Google on Privacy
Microsoft to blast Google for its copyright policy
Om Malik slams the Oscars for their YouTube policy
sqlite3 hnarchive.db "select ('[' || title || '](' || url || ')') FROM items WHERE type='story' and (title LIKE '%blast%' or REPLACE(lower(title), 'islam', '') LIKE '%slam%') AND NOT title LIKE '%blaster%' AND NOT title LIKE '%blastoma%' ORDER BY time DESC"
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Today, I re-downloaded a video that I already had a copy of. I was surprised to find that the video stream lost 33% of its bitrate. The bitrate was down from 600kbps to 400kbps, even though both files were labeled as f136, which is Youtube's 720p AVC stream.
This video is Tim Minchin's Storm. A classic.
Older copy, acquired September 2020:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : V_MPEG4/ISO/AVC
Duration : 10 min 38 s
Bit rate : 601 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 24.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.027
Stream size : 45.7 MiB (98%)
Default : Yes
Forced : No
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
VENDOR_ID : [0][0][0][0]
Newer copy, acquired July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : V_MPEG4/ISO/AVC
Duration : 10 min 38 s
Bit rate : 400 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 24.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.018
Stream size : 30.5 MiB (98%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Default : Yes
Forced : No
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
VENDOR_ID : [0][0][0][0]
Has Youtube found more optimal compression parameters so they can produce the same visual quality at a lower filesize, or is it just worse?
Click each comparison to enter fullscreen.
It's just worse. How dare they! I had to look for more examples.
I replaced about 90% of my youtube library in September 2020 because prior to that point I was not keeping the format code (f136, etc) in the filename. So, if there was any Great Re-encoding already underway by that time, I will have mostly missed it.
When you see "Stream size 24.2 MiB (100%)", please ignore the percentage. In my copies I of course have video+audio, but in today's test downloads I only fetched the video, thus they are 100% of themselves.
Weird Al - White & Nerdy (Take #1) lost 16% bitrate and artifacts were very slightly increased.
November 2017:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 7 s
Bit rate : 1 287 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 23.976 (23976/1000) FPS
Minimum frame rate : 23.974 FPS
Maximum frame rate : 2 000.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.058
Stream size : 28.8 MiB (91%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 7 s
Bit rate : 1 082 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.049
Stream size : 24.2 MiB (100%)
Title : ISO Media file produced by Google Inc. Created on: 05/25/2019.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2019-05-25 11:27:26
Tagged date : UTC 2019-05-25 11:27:26
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Rick Astley - Never Gonna Give You Up lost 7% bitrate and artifacts were very slightly increased.
September 2020:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 32 s
Bit rate : 3 159 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.061
Stream size : 79.8 MiB (96%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 32 s
Bit rate : 2 965 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.057
Stream size : 75.0 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-01-20 16:50:18
Tagged date : UTC 2023-01-20 16:50:18
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Kitty0706 - Moments with Heavy - French Toast lost a huge 74% bitrate. Artifacts are worse, but honestly not as bad as I expected.
December 2016:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 23 s
Bit rate : 966 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.035
Stream size : 30.4 MiB (88%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 24 s
Bit rate : 255 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.009
Stream size : 8.02 MiB (99%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-07-07 08:35:27
Tagged date : UTC 2023-07-07 08:35:27
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Mega64 - Final Fantasy XII lost 13% and got disproportionately rekt.
June 2017:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 23 s
Bit rate : 892 kb/s
Width : 640 pixels
Height : 480 pixels
Display aspect ratio : 4:3
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.097
Stream size : 15.3 MiB (87%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 23 s
Bit rate : 777 kb/s
Width : 640 pixels
Height : 480 pixels
Display aspect ratio : 4:3
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.084
Stream size : 13.3 MiB (100%)
Title : ISO Media file produced by Google Inc.
Encoded date : UTC 2019-11-03 21:14:23
Tagged date : UTC 2019-11-03 21:14:23
Codec configuration box : avcC
randytaylor69 - the moistening. lost 44%, though the difference is basically negligible outside of fine hair details.
July 2017:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 1 min 59 s
Bit rate : 2 237 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.043
Stream size : 31.8 MiB (94%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 1 min 59 s
Bit rate : 1 267 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.024
Stream size : 18.0 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2022-09-18 12:35:23
Tagged date : UTC 2022-09-18 12:35:23
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
POGO - Data & Picard gained 34% bitrate and artifacts were slightly reduced.
June 2018:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 16 s
Bit rate : 1 371 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 23.976 (24000/1001) FPS
Minimum frame rate : 23.974 FPS
Maximum frame rate : 23.981 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.028
Stream size : 32.1 MiB (91%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 16 s
Bit rate : 1 847 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.037
Stream size : 43.2 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-02-20 06:11:57
Tagged date : UTC 2023-02-20 06:11:57
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
GoldVision - Planetside 2 Savepoints - Don't be Greedy gained 10% and artifacts were reduced.
December 2016:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 57 s
Bit rate : 3 520 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 29.970 (29970/1000) FPS
Minimum frame rate : 29.970 FPS
Maximum frame rate : 2 500.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.057
Stream size : 74.6 MiB (93%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 57 s
Bit rate : 3 888 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.063
Stream size : 82.4 MiB (100%)
Title : ISO Media file produced by Google Inc.
Encoded date : UTC 2019-12-03 02:46:02
Tagged date : UTC 2019-12-03 02:46:02
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Ned Batchelder - Facts and Myths about Python names and values lost 68% bitrate with no meaningful loss in quality. It's a slideshow, after all.
March 2017:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 25 min 19 s
Bit rate : 636 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.023
Stream size : 115 MiB (83%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 25 min 19 s
Bit rate : 209 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.008
Stream size : 37.9 MiB (99%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2020-12-21 05:00:20
Tagged date : UTC 2020-12-21 05:00:20
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Demi Adejuyigbe - 9/21/18 gained 33% and artifacts were reduced.
September 2020:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 1 min 28 s
Bit rate : 1 480 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.024
Stream size : 15.5 MiB (91%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 1 min 28 s
Bit rate : 1 983 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.032
Stream size : 20.8 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2021-09-21 18:55:13
Tagged date : UTC 2021-09-21 18:55:13
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
DATA - Don't Sing gained 33% and artifacts were slightly reduced.
September 2020:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 51 s
Bit rate : 1 292 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.025
Stream size : 35.7 MiB (91%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 3 min 51 s
Bit rate : 1 730 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 25.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.033
Stream size : 47.8 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-06-06 01:02:54
Tagged date : UTC 2023-06-06 01:02:54
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
WASABI WOMAN gained 8%. Artifacting is slightly improved around text but is otherwise mostly a wash.
December 2018:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 30 s
Bit rate : 881 kb/s
Width : 854 pixels
Height : 480 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.072
Stream size : 15.9 MiB (87%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L3.1
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 30 s
Bit rate : 952 kb/s
Width : 854 pixels
Height : 480 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.077
Stream size : 17.1 MiB (100%)
Encoded date : UTC 2017-10-13 21:24:19
Tagged date : UTC 2017-10-13 21:24:19
Codec configuration box : avcC
OK GO - The Writing's On The Wall gained 53% and artifacts were pretty significantly reduced.
December 2018:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 18 s
Bit rate : 1 996 kb/s
Width : 1 920 pixels
Height : 1 076 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 23.976 (24000/1001) FPS
Minimum frame rate : 23.974 FPS
Maximum frame rate : 23.981 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.040
Stream size : 61.6 MiB (94%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 18 s
Bit rate : 3 071 kb/s
Width : 1 920 pixels
Height : 1 076 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.062
Stream size : 94.8 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-06-06 07:22:05
Tagged date : UTC 2023-06-06 07:22:05
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
David Foster Wallace - The Problem with Irony gained 35% and artifacts are very, very slightly reduced (not worth 35% in my opinion).
March 2022:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 9 min 53 s
Bit rate : 1 031 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.017
Stream size : 73.0 MiB (89%)
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 9 min 53 s
Bit rate : 1 398 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.022
Stream size : 99.0 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Gangnam Style lost 3%, with differences only appreciable under a microscope.
September 2020:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 12 s
Bit rate : 3 450 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.069
Stream size : 104 MiB (96%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
July 2023
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 12 s
Bit rate : 3 358 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.068
Stream size : 101 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2022-09-23 14:42:00
Tagged date : UTC 2022-09-23 14:42:00
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Weird Al - Another Tattoo lost 18%, yet the linework has been greatly sharpened, possibly too far to the point of aliasing. Whether that's true to the source I cannot say. This video's low-contrast papyrusy background is still pretty hell for blocking artifacts.
December 2016:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 50 s
Bit rate : 2 456 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.040
Stream size : 49.8 MiB (95%)
Codec configuration box : avcC
July 2023:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2 min 49 s
Bit rate : 2 021 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.033
Stream size : 40.9 MiB (100%)
Title : ISO Media file produced by Google Inc.
Writing library : x264 core 155 r2901 7d0ff22
Encoded date : UTC 2023-05-04 02:57:10
Tagged date : UTC 2023-05-04 02:57:10
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
I asked mediainfo for the bitrate of some of my files, and plotted them.
When sorted by video publication date, keeping in mind this is not the acquisition date and therefore would be impacted by any kind of Great Re-encoding that could have happened, I don't see much obvious pattern. You could say that fewer f137 videos are above 4000kbps since 2018.
When sorted by video acquisition date, I don't see anything worth speculating on. This data is simply not enough to work with. I would be much more concerned if I saw some kind of hard ceiling, for example if f137 suddenly stopped crossing 4000kbps, which it did not.
Some of the bitrate clumping could be explained by me downloading a lot of videos from a single channel, each a little different from the global average.
Fancy that.
This article would have been much more exciting and outrageous if all the videos got worse, and it's a shame that any of them have. But, as usual, the truth is less exciting and outrageous, and in most cases the re-encoded files look better or about the same. I'm totally pixel-peeping these comparisons, and I think you'll agree that even the videos that did get worse show underwhelming difference. Except Storm.
This experiment only shows a sample of 16 videos, which is perhaps not up to your standards of rigor. But I went into this expecting to find a clear decrease in bitrate and visual quality, based on my personal experience seeing blocking artifacts in almost every youtube video I watch. If that doesn't pan out after 16 examples, it seems like it would be pathetic and desperate to keep digging for some lucky gotcha. The bitrates have just been low the whole time.
The oldest file I have is from 2016, and the majority are from 2020 onward, so that limits the scope of this experiment. When I tested videos that I acquired during 2021-2023 I found the bitrates were almost always identical to before, so I did not mention them here. I think Youtube's re-encoder is not toying with such recent videos.
For what it's worth, you don't need to tell me that VP9 and AV1 will look better than AVC at equivalent bitrates.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Verbatim
Date | Game | Reason | Forgiven? |
---|---|---|---|
2014-10-12 | Revenant Part 2 | Lame ending | ✓ Will try better next time |
2015-10-17 | Construction Bob | Lame ending | ✓ Bought the game as a service to all of us who want to see what's behind the curtain of hell |
2017-09-14 | Hinterland | Lame pumpkin bombs | ✓ Offending pumpkin farmer promptly evicted |
2018-07-07 | The Crew | Cardboard story | ✓ You can drive all across the United States |
2018-12-24 | Apocalyptica / Deer Napped | Couldn't find the magic | ✓ Later trapped Satan in an asteroid and shot him off into space |
2019-11-28 | Harry Buster / again | Getting songs stuck in our heads | tbh I'm not sure if this one was forgivable |
2020-12-29 | SiN | Did not try so hard to get the soundtrack from Zak Belica as to receive a restraining order | ✓ It would have set a bad precedent and closed off the possibility of working with Zak to get other music in the future |
2021-08-24 | The Journeyman Project | Did not read a biography on Mohandas Gandhi in preparation for the episode | ✓ It probably wouldn't have helped anyway given the ambiguity of ethics towards outsourced mechacolonialism |
2021-10-28 | Gothos | Super lame ending twice in a row | Debatable |
2023-06-19 | The Legend of Kyrandia 2 | Petrified forest | ✓ Puns for the pun god |
Almost verbatim
Date | Game | Reason | Forgiven? |
---|---|---|---|
2015-04-01 | Wolfenstein | Gave up on game | ✓ Game was giving no motivation to keep playing |
2016-02-19 | Darkspore | Not giving more notice | ✓ Didn't even find out about it until THIS MONTH |
2016-07-08 | The Chosen - Well of Souls | Didn't mean for the episode to turn into a play-by-play of everything that's horrible about level 3 | ✓ You have to go with the stuff you remember and by god you remember level 3 |
2017-03-31 | Maabus | Lame ending | ✓ At least we can share it with you |
2019-08-31 | TrackMania² Canyon | Update makes game worse | ✓ Had no idea they were doing it and video was almost over anyway |
Honorable mentions
Date | Game | Reason | Forgiven? |
---|---|---|---|
2013-10-15 | Tyrian | Series is not a game-themed S&M show | ✓ As of Phantasmagoria 2, yes it is |
2014-10-31 | The Last Stand | People might be sick of zombies | ✓ Dealing with flash games so we don't have to |
2019-06-30 | The Cave World Saga | Not calling him Speedy | ✓ Liberating the world |
Date | Game | What did he see |
---|---|---|
2014-10-12 | Revenant part 1 | Singular mandatory fistfight |
2014-10-12 | Revenant part 2 | Excessive miniboss tease |
2015-12-22 | Still Life part 2 | Ending doesn't reveal the killer |
2016-02-19 | Darkspore | No backwards progression |
2016-07-08 | The Chosen - Well of Souls, again, almost | Extreme gameplay difficulty curve; poor game design |
2016-08-18 | Deus Ex | Real life politics and economics in a mainstream game |
2016-10-31 | Realms of the Haunting, again | Magic staff that only has one shot; abrupt and plot-omitting scene transition |
2017-03-31 | Maabus | Game-quit lottery |
2017-07-14 | Armed & Delirious part 2 | Randomized 512-option no-hints puzzle |
2018-08-16 | Requital, again, again | Healing potions that don't heal you; starting the game on Easy gives you free levels; other game design problems |
2018-12-24 | Apocalyptica / Deer Napped, again | Menu screen with blurred navigation items; snowmen shooting invisible projectiles with no accompanying animation |
2019-08-31 | TrackMania² Canyon | Irreversible update makes game objectively worse |
2019-11-28 | Harry Buster | Main menu singalong |
2020-04-06 | Black Future '88 | Soul of the Commodore |
2020-10-27 | Clans, almost, but it's rare | Big furry eye things with pincers that explode when you hit them; clicking too rapidly on the boss skips the game ending |
2020-10-30 | Hellgate London (almost, but it's rare) | Storyline with intended gameplay order, but not telling the player which path to take first |
2020-12-23 | Aida's Strange Christmas (almost, but it's deep in the subconscious) | Unmasked warlocks are weird spindly elephant people |
2021-10-31 | Martian Gothic | Skipping the dialogue gives you a gameplay advantage |
2021-12-24 | The Division | "Dual-monitor" graphical setting that slightly offsets the game UI for a central screen bezel, yet no ordinary FOV slider |
2022-06-17 | Mage Night Apocalypse, again, again | Levelling up without clicking anything; winged, amorphous, armored blob thing; airship takes off and crash lands with no airtime in the middle |
2022-10-30 | Killing Time | Game provides in-universe reasoning for the weapons and ammunition found scattered throughout game world |
2023-06-19 | The Legend of Kyrandia 2 | Enforced puns |
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In the early 90s, David Foster Wallace wrote an essay called E Unibus Pluram: Television and U.S. Fiction. It was published in the June 22, 1993 issue of Review of Contemporary Fiction.
In honor of its 30th anniversary since publication, I've done a narration of it. FLAC, about 328 MiB:
Wallace's writing is extremely dense — I would not recommend multitasking to it — and uses some complicated vocabulary words that I probably mispronounced, so I thought it would be nice to provide a scrolling text video to act as a simple accompaniment:
This essay arrived to me via Will Schoder's 2016 video David Foster Wallace - The Problem with Irony. This was when my interest in film was growing, my patience for advertising was shrinking, and I was seeking out more media critique.
I'm posting this article to my /writing page, primarily because I don't have a separate RSS feed for purely audio or video releases, so I feel like I need to write something here to justify it. But really, I'd rather let Wallace's words speak for themselves, and I'm just going to provide a few bullet points that come to mind insted of trying to prose it out:
Wallace's messages about advertising are basically foundational to my opinions today. From the point about ads becoming more hpynotic and visually engaging so people don't change the channel, to ads mocking themselves first so that all viewer critique is second, I owe much of the time I've spent thinking about advertising to E Unibus Pluram.
Wallace asks "What implications are there in our sustained voluntary immersion in stuff we hate?" to the audience with respect to what's shown on television, but the same question could be asked to Wallace with respect to the time he spent writing this essay, and to me for writing my advertising article, and so forth. It feels good to criticize and call out and debunk. But maybe we'd be happier if we took the Mr. Rogers or Bob Ross or Field of Dreams approach, putting our hours and effort into leading by example. I don't think you'll find a clip of Bob Ross tearing apart the contemporary art industry...? Obviously Wallace wrote books too, this wasn't his whole output. It's just that it's tempting to think that critique leads to enlightenment when in actuality it probably leads to misery. Here I am gushing over this piece of critique and how much smarter it has made me, rather than something else. I'm also in the aura.
Every hour that I spend watching a movie (fictional stories of fictional lives) or a youtube video (somebody else's life, activies, travels, creations) is an hour that I am not really putting into my own life, activities, travels, or creations.
The paragraph about the "earnest gray eminence" is one of my favorites in the whole piece. The most obvious takeaway is that a lot of media critique boils down to "it's wrong because I don't like it", and there's a kind of status-quo syndrome that assumes the world we were born into is the timeless "normal". There is another takeaway I get from this: in the short term, fictional stories are fiction; but in the long term they practically become nonfiction, documentary. Even if the characters didn't exist and the events didn't happen, the fact that the author considered them plausible enough to write essentially captures the state of the environment, culture, and technology of the time. In the distant future, that's what will matter to anthropologists.
I do not think I have fully internalized the concept of irony as Wallace discusses it, and I do not think I would be able to competently criticize a work as being ironic. I can understand irony as sights contradicting sounds, but Wallace gives the impression that practically all media is drowning in excessive irony, which has not clicked for me yet. "Irreverent" writing and and authors "afraid of sincerity" are easier to spot: recent blockbuster movies along the Marvel and Star Wars lines have been criticized for dropping too many jokes into serious or emotional scenes, as if to say "gee, it's a good thing we're not actually feeling anything here, that would be embarrassing". But I think there is more to irony than this, which I would not spot without help.
The last section of the essay covers George Gilder's 1990 book Life After Television, and the concept of a "telecomputer, a personal computer adapted for video processing and connected by fiber-optic threads to other telecomputers around the world". By 1990, the World Wide Web was just about to become generally available, so you shouldn't interpret this as Gilder predicting the internet or digitally-encoded video, exactly. Nevertheless, it seems to me that his predictions for our applications of digital video are without fault, thirty years later. Wallace died in 2008, when video delivery over the internet was still very restricted technologically. Unfortunately, I do not think he'd be happy with where we're at. Dependence on electrified furniture is perhaps down, but dependence on electrified pocket squares is up.
I think Wallace paints a picture in which the majority of Americans are lonely and depressed. At the top of the essay, he says that average households watch six hours of TV per day, and lonely people watch more than that. But throughout the rest of the essay he mostly drops the distinction between average and lonely and continues to use the six hours figure while treating everyone as lonely. In one paragraph, he says "Let's for a second imagine Joe Briefcase as now just average, relatively unlonely, adjusted, ...", but that only lasts for the promised second and then Joe Briefcase is right back to being lonely. Considering the fact that Wallace suffered decades-long depression, and ultimately took his own life, I think it's likely that his perceptions of the average person here were not accurate to reality, and I say that in the most well-meaning way. It is human nature to assume that most people are similar to ourself. And although I daren't be so sincere as to admit to any kind of depression, I find myself in ordinary social situations feeling just how out of the ordinary I am. The kinds of people who spend lots of time thinking about societal problems — media, advertising, capitalism, ecology, urbanism, nutrition — find themselves wondering why is nobody else seeing what I'm seeing here?? or, less politely, wake up sheeple!!. Most people do not feel like this. The average person is probably not quite as anguished as Wallace assumes them to be. Which is not to say they are well-nourished.
Some behind-the-scenes remarks about my read-along video:
I don't make a lot of videos and I don't know what video editor would typically be considered the best for producing this kind of thing. The only video editor I have is an older copy of Adobe Premiere (from before they turned subscription-only) and it could not handle such a huge amount of text in a single text box. I of course did not want to bother with managing tens of smaller-but-still-as-large-as-it-can-handle text chunks or downloading other editors. I wouldn't be surprised if 3Blue1Brown's manim could be coerced to perform this, though, since the goal of scrolling text is so easy to define programmatically. If I needed to make a lot of these I'd probably try.
But, I don't need to make a lot of these, I just needed to make one. So, I prepared this HTML page that scrolls by itself, and recorded the screen with OBS. Yes, it took 144 minutes, but that's fine because I just set an alarm and took a nap.
To set the pace of the automatic scroll, which varies over time, I added data-timestamp
attributes to each of the headers and several of the paragraphs to act as keyframes, and wrote javascript to choose a speed between each keyframe. I did not bother to add any seek functionality because it only needed to work once.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In December 2020, I downloaded an app called Trackbook by author y20k. This records your GPS position while you walk, hike, drive, or bike, so you can see where you went. GPX is a standardized XML format for storing these tracks.
There are quite a few Android apps for recording GPX files, but I always found Trackbook to be the most pleasant to use for both its aesthetics and simplicity. I submitted some bug reports and even stumbled my way through Android Studio enough to make code changes and submit a few pull requests, which were merged.
GPX files are helpful for contributing edits to openstreetmap, because you can more accurately trace out paths that might not be clear in aerial photos, and you can publish the GPX for other mappers to reference as well. You can also use the GPX to know where you were standing when you took a photo of a point of interest, so that you can position the POI more accurately on the map. This is better than relying on EXIF geotagging in some cases.
Besides being useful, I think GPX recordings are fun. I don't need a GPX to help me map out a sidewalk, but I record my walks anyway because it's cool to see where I was at some time in the past. Much like a photograph, a GPX recording is an artifact by which to remember the day.
Now that I've recorded more than 100 GPX files, I have become quite fascinated with dumping all of them into JOSM and seeing every single track overlaid on top of each other. The rivers of common routes and spiderwebs of distant destinations are very pretty. I zoom in and out, recognizing locations by their pink periphery against a plain black background.
In March 2023, I became seriously interested in the idea of recording GPX 24/7. I started to think about how awesome these pink rivers and spiderwebs would look if every single path were lit up. Until now, I had primarily used Trackbook to record deliberate outings and special trips. And that's great, but it meant that my track collection mostly showed little disconnected bubbles of places I've been to only once or twice because I didn't typically record day-to-day events. Also, if I was driving to a location to hike at, I'd intentionally wait until I got there to start recording because the drive would dominate the statistics like distance travelled and average speed. What's worse is that I would sometimes forget to start recording at all, and I'd miss the whole day. I knew that micromanaging the start and stop time of each recording for the purpose of statistics was silly, and that it would be better to collect as many trackpoints as possible and then make sense of it in post.
Initially, I was concerned that if I recorded too many tracks, the boring commutes would drown out the interesting trips, but it turns out that boring tracks are actually interesting too, given time. Seeing how easily JOSM handled the quantity of points I loaded into it gave me confidence that I should proceed. It is probably better to regret having too much data than to regret not having it.
However, the data structure and user interface of Trackbook are not geared toward 24/7 recording. It is designed for recording outings with a distinct start and end, and this presented me with some friction in using it the way I imagined.
I sat on the problem for a very long time, and then I finally decided to make a fork of Trackbook called trkpt that takes the data model in a direction more suited to my goal. This is my first time forking someone else's project and republishing it with a new name. It makes me feel somewhat guilty, or rude, but it's ok by the license and I'm enjoying the freedom to make this work just how I want it.
Basically, I swapped out the JSON-based file storage with an SQLite database, and removed the entire concept of "Tracks" as a stored object. Instead, the database of trackpoints is queried on the fly to produce tracks with any start and end time you want, which you can export as GPX files. This also opens the door to JOSM-style megarenders and geospatial queries like "what day was I here?". I even made it pink.
I also added "homepoints", which are points you can put on the map around your home or workplace so that trkpt does not record any trackpoints there. Due to GPS's natural inaccuracy and drift, which is especially bad when you are indoors, you tend to get large clouds of points around buildings if you leave the recording on, so homepoints eliminate that.
In the first draft of this article, I wrote:
I do not literally run trkpt 24/7 just yet, because my instinct for optimization doesn't like the thought of leaving the GPS at full power all night long and at work, capturing tens of thousands of fixes that are immediately thrown away; or worse, struggling to capture a fix at all. It is hard to shake the somewhat superstitious feeling that it would have a negative effect on my phone's long-term battery lifespan. Maybe I will find a balance that reduces power consumption near homepoints without sleeping the GPS so much that it is late to capture departures. These mental blocks are the only thing in the way of me running trkpt all the time, so the code changes themselves have been successful, I think. I am still starting trkpt when I wake up in the morning and turning it off at work. But for day trips on weekends I record the whole day with no stress, thanks to the flexibility of the new data model.
But, I sent an email to y20k to share my work with him, and he suggested using the device's accelerometers to improve the sleep/wake cycle and conserve battery. This really helps!
Android provides a significant motion sensor which, while implementation surely depends on the manufacturer, is meant to be used in low power scenarios where a latency of several seconds is acceptable. When we are near a homepoint, we can reduce the polling frequency of the GPS to once per minute, or perhaps five minutes. As soon as motion is detected, we can wake it back up to full power, so that by the time your shoes are tied, your fix is hot again.
When I am at work, my device struggles to acquire any GPS fixes at all, so trkpt can't even know if I'm near the homepoint. In this case, there is no benefit in reducing the polling frequency of the GPS. If you ask Android for one location per minute and it has to struggle for several minutes to get a single fix, then you're not saving anything. The GPS burns a lot of energy in this state and it's better to turn it fully off. This means we are placing a lot of trust in the motion sensor to restart the GPS, so I will see how it goes and continue experimenting with the balance between all these features.
Anyway, the code is the easy part. Now I have to do the hard part which is actually going out to interesting places more often and turning the world pink.
Thank you y20k for making Trackbook!
I have been using trkpt to record every single day for the nine months since this article was first published — a total of 265 tracks! On the whole I feel it has been very successful.
I have been using a Unihertz Jelly 2 exclusively for trkpt. I had bought it for another reason in 2021 and repurposed it as a unitasker for this role.
But, having experienced both the advantages and disadvantages of using a cell phone as a 24/7 logger for nine months, I decided it was time to buy some made-for-purpose hardware. After quite a bit of research and quite a lot of hemming and hawing, I finally bought the Columbus P-10.
It took me almost two months of indecision before I finally caved. The singular cause of this indecision was the fact that the Columbus uses Micro-USB instead of USB-C. In my opinion this is unforgiveable in 2023 at the price of $240, but I can still use it without forgiving it. A separate-beds kind of relationship. Now I need to keep an additional cable on my desk and in my car — a cable I thought I was done with. There are simply no other competing products on the market in this form factor doing USB-C, the closest being the Bad Elf Flex Mini which is a big chunky device for surveyors.
Here are the main problems I encountered with the phone that pushed me to upgrade:
Fighting the device: Android has heavy eyelids. All it wants to do is doze. Doze most often leads to missed points during car trips that are longer than about 45 minutes. The phone's accelerometers keep the device out of doze while you are walking, but there are not enough g-forces for this in a car except in particular life-threatening circumstances. Battery-saving exemptions, foreground notification services, and wakelocks are not enough to convince Android that you really do want to keep trkpt running the whole time. I think what's possibly happening is the app itself is staying awake, but the location subsystem is going to sleep and so trkpt receives no data.
Maybe if I rooted the device I could fully disable doze, but I'm afraid of bricking it and I don't want to go down that road. If the phone is plugged into a charger it will stay out of doze forever, but this option is not available when I am a passenger in someone else's car. I can also hold the device out with its screen on the whole time to prevent doze, but then I have to explain my weird interests to other people so I don't like doing that. It suffices to say that this anxiety / micromanaging around doze is not in line with my goal.
Besides doze, I also encountered an occasional operating system crash with the phone. Maybe three or four times this year, I took the phone out of my pocket to find that it had reboot itself. That's still pretty impressive, all things considered, but the Jelly does a few other things that make me doubt its software stability. It's a cool device, but when a company as small as Unihertz makes as many different models as they do, you just know they're cutting corners, and software is definitely one of them.
Cell phones don't really want to be unitaskers, and while it is possible to whip them into shape, I get tired of doing so much whipping. I'd rather have something that's not a fight.
User error: From time to time, I have stopped the trkpt recording, either to do some database edits or to reboot the phone or whatever, and forgotten to start recording again. My biggest blunder was when I edited my trkpt database file on the computer without waiting for Syncthing to fully synchronize with the phone, which caused a Syncthing conflict. For five days, the phone continued recording to whatever file handle it still had open, but none of the data actually got saved, and I didn't notice until I wanted to do an export of the week. To help prevent this from happening again, I went ahead and changed the trkpt code to re-open the database handle when resuming a track.
Track accuracy: One of the reasons I used the Jelly for trkpt instead of my primary LG phone is that the Jelly's positional accuracy is simply better, and I was always pretty satisfied with it. However, there was still room for improvement:
The Columbus solves these problems because it is single-minded and never stops recording, and the flashing lights confirm it is working at a glance so I am unlikely to leave it off by accident.
For what it's worth, I can confirm that battery life was never a problem with the phone thanks to the accelerometer-based sleep/wake system and homepoints.
The manufacturer's claim of lane-level accuracy is well earned. Assuming that Bing's aerial imagery is aligned more accurately than my equipment, I can see that although my tracks don't always run straight down the middle of a car lane, they are within the lane, and lane changes are unambiguous.
Undeniably, the phone has some advantages which I am sacrificing here:
Syncthing: On the phone, I have set Syncthing to run whenever it is plugged into power. So as soon as I get home and take my stuff out of my pockets, my trkpt database is synced to my computer. With the Columbus, I have to plug it into my computer and copy the data over (more on this below). I know this sounds the same, but to be more clear, I like to charge my phone using a desktop power adapter instead of plugging things into my computer, to keep my computer free of dangling wires and snag risks. And did I mention I have to use a Micro-USB cable?
Immediate review: Because the Columbus does not have a screen, I can not look at my track until I get home. Besides the entertainment value of watching the line draw in real time, the immediate review was sometimes helpful if I wanted to ask "where did I start?" or "which path did I just take?". Of course I can still run trkpt on my normal phone if I really think I'll need to do that.
Customizability: The great thing about open source code is you can just change it whenever you want. All that stuff about homepoints and sleep behavior can be customized for trkpt, but the Columbus is not open source and you have to make do with the options in the config file. Fortunately it is comprehensive enough, offering a minimum movement speed to reduce stationary point spam, and accelerometer-based move-to-wake.
I've had the Columbus for two weeks now and so far I think the upgrade has been worth it.
Earlier, I said that it's "better to collect as many trackpoints as possible and then make sense of it in post", and now I'm being held accountable for my words. The Columbus gives you the option of recording straight to GPX files, or to NMEA sentences. The NMEA format is as close to raw as the end user can get, and even disables some of the in-device filtering options. Naturally I picked that.
The Columbus does not have anything like my "homepoint" feature, which is understandable, so every day I come home with huge clouds of point spam at my workplace (partly because it is better at capturing points indoors!), which I delete before exporting to GPX. I do not want to be in the habit of turning the device off when I arrive, because I'm certain I'll forget to turn it back on again from time to time. Collect everything and make sense of it in post.
So, I'm on the hook for doing whatever kind of filtering or pruning I want to do as part of my intake process for the NMEA data.
I started by writing a Python program that detects the mounted storage device, finds new NMEA files, and inserts the points into a trkpt-format SQLite database. This means the ingest is basically a one-click operation. It could maybe become zero-click if I detect the USB device with a scheduled task.
I used pynmea2 to parse the data, and had to combine the GGA sentences which contain number of satellites, altitude, and HDOP but no date (why?!); and the RMC sentences which contain the date.
During this import, I do some filtering to remove points I don't want, but I always keep a copy of the source NMEA file so I can go back if I ever change my mind. I could add a few more checks against homepoints, but I haven't yet. You see, one of the weaknesses of the homepoints is you have to give them a large enough radius to swallow up the stray, low-accuracy points that the device generates while you are indoors, but this radius winds up being so large that you lose the legitimate, high-accuracy points of your approach to the building and your movement in outdoor spaces near the building. I want to enjoy those for a while before I start filtering them out.
Then, Syncthing syncs that database over to my normal phone, and that's where I use the trkpt app to delete any more points I don't want and export to GPX. I know that sounds kind of stupid, and I would like to make a PC program for doing this instead, but that kind of GUI with pannable/zoomable points is not something I know how to make at the moment. Someone made a tkintermapview widget, but the framerate is not very good and I don't think Python is the right tool for this job, unfortunately.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>time travel, teleportation
free healthcare for every nation
intercontinental zettabit link
rat submerged in air you can drink
zero latency, faster than light
stardate eternity, fish taught to write
launched in a second, stopped on a dime
arriving at noon, malacandran time
journey to mars, the center of earth
without spacesuits, for whatever it's worth
total comfort, seat reclined
on the way to planet nine
trip to k-pax, walken communion
meteor crater, starman reunion
nemo nobody, cryostasis
ten billionth flight to outer space is
free for all passengers, no cost to ride
surplus of everything, entropy died
people congregate in fair city
centers, living post-scarcity
no owners, no renters, no debt collectors
for there is no debt, no cause for defectors
knowledge transferred, proliferated
global population educated
medical magic, the mind's potential
alzheimers, dementia made nonessential
diseases diverted, death defeated
genome sequenced, spliced, completed, repeated
isaac asimov brought back to life
resurrect anybody, next up, his wife
return of the dodo, all species befriend
extinction never to be seen again
flawless evolution, mammoth clone
forget prosthetics, limbs regrown
lungs rebuilt, heads transplanted
foods pasteurized and never rancid
nutrition, diet, puzzles solved
protein shake contains dissolved
vitamins, minerals, sugars, fats
even made my hair grow back
novelty molecules, stable arrangements
made fresh at home as seasoning agents
chemistry conquered, and with it, physics
mathematical constants pay me a visit
np-easy, log-log bound
fifth dimension sights and sounds
algebraic breakfast, quantum dessert
daily discovery, breakthrough first
sinusoidal poetry, the meanings in fields
electromagnetic, temporal, deftly revealed
through fourier transforms, the radio spectrum
fluently spoken by kids in their bedroom
alien lifeforms on the phone
catch up, chit-chat, we're not alone
cybernetic translator, perfectly clear
kisses from terra, wish you were here
peace with the xenomorph, love for the past
everything built with intention to last
shoes with soles that don't grow old
guaranteed one stroll from pole to pole
dwellings made from local clay
built by one in just one day
efficiently heated and passively cooled
with nothing but architectural rules
bottomless gigabytes to store all your stuff
yet feeling content what you have is enough
forcefield, atlantis, undersea dome
heart of the volcano that i call home
source of fire that does not smoke
becomes invisible under this cloak
tea, earl gray, hot from the replicator
jauntily circumnavigate the equator
phasers, sabers, blasters, beams
einstein's ride on a wave of dreams
fountain of youth, refreshingly cool
hal ten thousand saves frank poole
portal gun, gravity cannon
blueprints courtesy of s. r. hadden
everlasting gobstopper, endless canteen
friends hanging out on tatooine
plant matter, biofuel powers the land
thirty three gigajoules from just half a gram
of flower petals, falling, settled
on long-disused mines for heavy metals
forests recovered, trees replanted
obsolete tools dismantled, recanted
replaced with new ones as time passes by
restoring the ozone in the sky
hovercraft, jetpack, rocket shoes, wings
robot assistant brings me my things
processors purring, a gentle buzz
i say computer, imagine, and it does
silicone wafers led to free thinking
water, water everywhere, all safe for drinking
study with socrates, dine with his mother
ted told us be excellent to each other
telepathic mindwaves, toilets with bells
and whistles and three seashells
music broadcast across the galaxy
lovely miss universe of diverse anatomy
now so far this is all quite simplistic
but if you want to hear something futuristic:
how about a taskbar you can rearrange
up down left right unconstrained
audio signal carried on a line
tip ring sleeve, timeless design
such simplicity and ease
let's make smarter things with these
an interface whose color can be changed
styled, freely themed if so deranged
interoperable protocols sans garden walls
compatible messages, encrypted, all
words spoken softly on wires
unsold, unhired by advertisers
online, offline, hardware switch
computed locally without a hitch
a cable functions on my behalf
facilitates the six-inch data path
from point to point or box to box
without dns and thirty hops
options, menus, controls, the works
no microservices, my gigahertz
datamined data, mine, unconfined
open standards, spec defined
it just plugs in, it just connects
i trust it works without defects
and lest it break by my own mistake
or wear with age, from old books we take
a useful page, repair
with parts acquired fair and square
don't be fooled by malediction
none of this is science fiction
all could be ours, i've bated breath
the technology just isn't quite there yet
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In the previous episode, I said that taking pictures of friends and family was the most worthwhile thing I can do with photography at the moment. In this episode I will detail how exactly I'm going about giving these people copies of the pictures to keep for their own memories.
For the purpose of this discussion, I'm not talking about sending a single picture by MMS or email attachment. I'm talking about sending 100+ photos of an event or outing to one or more people at full resolution, files of about 16 megabytes each. I have been improving this process over the past few months with photos going out to friends, family, friends-of-friends, coworkers, concert performers, and the parents of a youth sports team.
The end results are pages that look like this: https://files.voussoir.net/2022-11-12%20Sharing%20Photos/gallery.html
The first step is to take the pictures. This step is very important.
I am currently using Honeyview to review and cull photos. I like that it has minimal interface elements and a good fullscreen mode.
I don't do much editing, but some pictures need a bit of level adjustment due to harsh sunlight or missed exposure. I do this in Photoshop, but Photoshop has an annoying habit of trampling all over the EXIF data as if it owns the place. I always make a copy of the original photo before doing these edits, so that afterward a quick call to this exiftool bat file can put the EXIF back where it belongs. You may say that this results in dishonest metadata, but to me that is less of a sin than letting Adobe put its name all over my files.
For hosting and distributing the files, it is important to me that the system is under my ownership, for a few reasons. Firstly, the HTML that I can put together is better for the purpose of looking at and downloading original pictures than the interface you'll get from most image sharing or cloud drive websites. Secondly, I want all of these files to be private, or at least non-indexed, because I respect my friends and don't want to make pictures of them public on the internet. They can download their favorites and put those on social media if they choose to, but I won't.
The website you are reading now is currently hosted on an OVH VPS, which comes with 20 gigabytes of disk space. I can pay more for more space, but the cost is not economical for the purpose of cold storage of static files. I decided to make an account with Cloudflare R2, whose billing is much simpler than Amazon S3 at 1.5¢ per gigabyte of storage per month and no cost for ingress/egress bandwidth. This is cheaper than any kind of Flickr Pro or Google Drive, and is accessible by command line.
In order to give my R2 bucket a domain name, I had to move my DNS nameservers to Cloudflare's. Adding A records on my registrar's DNS was not good enough because Cloudflare does special serverside checks of some kind. If I am wrong about this and it's possible to use R2 with non-cloudflare nameservers, please email me as I'd like to know. I am not thrilled about making this compromise but, obviously, the other factors outweighed it. I turned off all of Cloudflare's enabled-by-default caching / traffic routing for the rest of voussoir.net. All of the files I upload to R2 are publicly accessible by just their URL, but since there are no directory listings it is not really possible for search engines to discover them unless someone I've given the link to has put it online [1].
I wrote photo_rename.py to rename the files from "DSCF0001.jpg" to timestamps. Even though we live in an age of 10 to 30 fps burst shooting modes, a lot of cameras still don't put subsecond timing in their EXIF data, mine included unfortunately. So, photos from the same second are marked as x1, x2, etc.
I wrote photogallery.py to generate a simple HTML page. Remember, the goals are to look at pictures, so there is no "page 1... page 2... page 3..." nuisance or teeny-tiny thumbnails as you'd get on most photo gallery websites; and to download pictures, so every element links to the full res file and an <a download>
button is added to every photo for additional convenience. This requires that the server allows hotlinking, which you don't typically get from cloud drive providers but you do get from object storage providers. The image links are target="_blank"
so that if you miss the download button, you get the big photo in a new tab and don't lose your scroll position on the gallery. photogallery *.jpg --title "2022-11-12 Sharing Photos" --urlroot "https://files.voussoir.net/2022-11-12 Sharing Photos/"
prepares the HTML, and I usually go in and add some kind of greeting like "Hi everyone, here are the photos from today's event, please enjoy".
I use resize.py to prepare the gallery thumbnails. resize *.jpg --width 1024 --height 1024 --output thumbs\small_{filename} --quality 80
does the job. 1024px is large enough to comfortably browse the photos without clicking through to the big version of each, and the thumbnails are decently light and not too jpeggy at about 125-150 kilobytes on average. I make sure to put the word "small" at the beginning of the thumbnail filename so that if someone downloads the thumbnail instead of the full picture by mistake, it should be pretty obvious unless they are particularly undiscerning, in which case their ignorance is bliss.
I followed Cloudflare's guide to set up the AWS S3 commandline utility for use with R2 (one, two, three) and I put that in a shortcut file on my PATH. So, voussoirr2.lnk
points to C:\Python\__latest\Scripts\aws.cmd --endpoint-url "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.cloudflarestorage.com"
. I call voussoirr2 s3 cp . "s3://voussoir/2022-11-12 Sharing Photos" --recursive
to upload.
I log into the R2 web interface to make sure the photos went where I intended, and then I give out the link to the gallery.html file: https://files.voussoir.net/2022-11-12%20Sharing%20Photos/gallery.html
If I wanted to, I could prepare a zip file containing all the photos and upload that as well, so that viewers could bulk download. If I was doing some kind of contract work, delivering a photo package to a customer, I would. But friends and family don't really care to download all 100+ pictures from a day. They'll pick their favorites that contain themselves or their kid, so bulk downloading is not necessary for the task at hand.
Wow, it's just that easy!
[1] If I wanted to further prevent indexing, I would write some clientside javascript to prompt the user for a gallery password which is integral to the path of the photos. The password would not even need to be hashed. As long as HTML never statically contains the true links to the photos, no off-the-shelf scraper would find them without the out-of-band password. It's not Fort Knox, anyway.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Over the past three years I have been taking more and more pictures. Up until now, it has always been with a cell phone.
I was growing increasingly unhappy with the low quality of the pictures. What's the point of all those megapixels when they look like soup? I hemmed and hawed over buying a real camera for a while but wasn't sure if I would really use it enough to justify it.
In May, I borrowed my dad's camera and took pictures of people at a renaissance faire. When I look at those pictures now I am still proud of how they turned out. That day assured me that my eye had outgrown my cell phone, and I made my purchase not long after.
The renaissance faire was a good venue for my first real photographic outing because there's a bunch of interesting looking people all in one place, all enthusiastic about or at least content with having their picture taken. It's like street photography lite because you don't have to worry whether you're going to look weird for taking pictures of strangers.
After I got my camera, though, it was a while before I really went anywhere. I just took walks around town.
I don't have an instagram account. I don't have a twitter account. I haven't put any pictures on reddit. I did make a flickr account, but then I deleted all the pictures out of it anyway. My pictures go here and it's got an atom feed with probably zero followers, but I wouldn't know because I don't keep traffic stats. I post full resolution images with no watermarks, and no that's not a mistake. Methinks I doth protest too much, but suffice to say I'm not trying to do 'social media' or get super popular with my photos.
Despite all of that, I became very aware, very quickly that my choice of subjects to photograph has been heavily skewed by my internet-centric mindset, surely a symptom of having spent too much time indoors. What I mean is, even though very few of my pictures get put online publicly, nearly all of the pictures I took in the first two months of owning the camera were composed to be safe for public consumption, i.e. contain no identifying features that could doxx me. They were closeups of anonymous objects: lamps, traffic cones, benches, trash cans, birds on wires, squirrels in trees, flowers and leaves. Very occasionally a signpost at eye level, my whereabouts concealed by a shallow depth of field. No roads, no landscapes, no skylines, no business names or home addresses or street signs. Pointing the camera at a named building or street felt wrong in the way that pointing it at a person through their bedroom window would be wrong.
This is a bad habit. It suggests that the motivation for taking the pictures is not to remember my own life, or to make something that makes me happy, but rather to get validation from internet strangers with internet-safe images. And that's really not a good thing.
After making myself conscious of this foolishness I have started to break the habit. I really don't want to look back on years' worth of photos and see a thousand plants and building corners and discarded shoes in parking lots, so I'm trying to get more of my actual surroundings. I have gotten a couple pictures of my city that I'm quite happy with, but naturally I won't show them to you. The pictures I put on my website are either abstract closeups of anonymous things, or else were taken far from home.
I also think it's worth being conscious of the difference between taking a beautiful picture and taking a picture of a beautiful thing. The architectural pictures I've taken so far mostly fall into the latter. I've got a few that I think are pretty striking, visually, but they also make me feel like a bit of a dope. Somebody spent months designing this building, somebody else spent millions financing it, somebody else spent months constructing it, and I spent eight seconds looking at it. The photo is not the art, the building is the art and my photo is just showing it to you.
My tone so far seems a little too self-critical, so let me lighten it up a bit. The reason I took all those pictures of random objects is not just because I was afraid of more meaningful scenes. It's because cameras have a way of making things look better than they do in reality, and suddenly everything is beautiful or interesting. With a new camera and an eye fatigued by bad cell phone pictures, it's like "wow! wow! wow!" every few minutes. Part of this is thanks to longer focal lengths, which is why I made sure that the 55-200 was my first lens; only later did I also buy the 18-55. So, it was something I had to get out of my system, and I think most people with their first camera could relate. Once I became accustomed to pointing the camera at something and having a good-looking picture come out, then it was on to the next challenge: making a picture that's good-looking and meaningful.
Getting smiles and poses from people who want to have their photo taken feels good. In the short few months that I've had my camera I've already had three strangers strike up conversations about photography, and two others who asked me to take their picture just because. But I much prefer candids over posed smiles. Making mundane and unposed actions look interesting and attractive feels like an accomplishment and a compliment to mankind, which probably needs a few more compliments at the moment. I like the idea of making art from non-art.
I am drawn to the genre of street photography. The problem is, I live in a car-dependent suburb which is very, very bad for "street photography" because everybody drives everywhere and the streets are empty of actual people. And because I, too, drive to work and to the store and all that, it's not like I can integrate photography into my commute — it has to be a deliberate outing with the camera. I take walks through miles and miles of samey-looking residential areas: single family houses, wide asphalt streets, sidewalks, yards; and I do get bored of it. The plus side of this is that I've started making more frequent and more deliberate efforts to go places I haven't gone before, which is good for me.
The abstract closeups I take around town are like eye candy: they're fun to look at for a moment, but are mostly hollow after a brief "hey, that looks cool". The street photography and the social interactions that come from carrying a camera in a busy place are better: they make me feel connected with community and leave me with positive memories of places I've been. But I don't look at other people's street photography. It's pretty boring.
What I'm feeling now is that the most important and meaningful kind of photography for me to do is of family and friends and people who will actually care to have the pictures. I am not Cartier-Bresson or Maier or Eggleston. I think I've taken some nice photos but I don't expect any stranger to care about them for more than a few seconds. I can enjoy looking at my own pictures, but once they start to pile up into the thousands even I can't give due appreciation to each one. I want my work to be appreciated by others, as we all do. If I take pictures of family and friends, then I've got at least one person who can say "that looks good", and mean it, and matter, and maybe even hang on to it.
I overheard one of my coworkers talking about an upcoming jiu jitsu open mat and (multiple days later, after working up the courage...) asked if I could come and bring my camera.
I also brought it to a concert.
And in both cases made a lot of people happy with results I'm very proud of. Being able to give people this kind of gift seems a lot more valuable than posting arty pictures of strangers for strangers to see.
Last year, I scanned my family photos from the 80s and 90s. It changed my approach to photography. Now, I photograph things I want to see in a few decades' time. People and places. The interesting and mundane moments in life. Bits that say 2022 to me. Things that I think will be gone in 10 or 20 years.
I do not take pictures of flowers etc now. I really, really didn't care about seeing pictures of flowers from the 80s. I'm far less focused on making photos perfectly framed and technically perfect - I'd rather just make sure I get the moments. A blurry, overexposed photo from my childhood brings back almost as many memories and feelings as a technically perfect one.
There is a John Waters movie called Pecker about young John Connor, having defeated the T-1000, living in Baltimore and taking pictures of his modest, low class friends and family. I am jealous of his confidence. I would like to be the kind of person that carries the camera everywhere, but I am still too shy and embarrassed.
The embarrassment issue continues to be difficult for me to reason about. When I look at an album of family pictures or videos spanning decades back — pictures of people in their living rooms, kitchens, backyards, schools, clubs, and events — I don't ask myself what makes it valuable. But if I try to place myself in that photographer's shoes and imagine that moment as if it were the present... it makes me shiver with embarrassment. "Hey everyone, look over here, this is a valuable moment that needs to be captured and memorialized forever", the snap of the shutter says, loudly. "You're going to die some day so I need to get pictures of you standing around while I still have a chance". I'm not sure I could bring myself to do it.
This whole photography thing of mine is pretty recent, so I don't have a reputation for carrying a camera. To suddenly start bringing it everywhere I go and taking pictures of people doing ordinary things and saying "you'll thank me in ten years when this ordinary thing becomes nostalgic" is nearly as cringe as dressing up like Eminem and telling them that I've found my life's calling in rap. There's vomit on my sweater already. A lot of this comes from my own dislike of being in front of the camera. Growing up, I always avoided my parents any time it was out. I have not fully calibrated how other people feel about it yet. And don't tell me I'm artistic.
We are no doubt saturated in photo and video today, with everyone carrying at least a dozen megapixels and two focal lengths in their pocket at all times and posting selfies on the internet for the world to see. So by that metric I think the average person doesn't mind having their picture taken, but a real camera and lens shows a premeditated intent that I think is intimidating, still. You can't pass it off as a spur of the moment.
On the plus side, the embarrassment thing is only a big problem when trying to do the candid slice-of-life stuff, and only with people who already know me and wonder where the sudden interest has come from. It's a lot easier when there's a clear event going on, and with people who don't know me yet. The jiu jitsu practice is a good example of that.
I have started paying more attention to photographs that I see in public. At a restaurant, I'll see pictures they have hanging on the walls showing the founders cooking in the kitchen or laughing with guests. At a library I'll see pictures of now-historic but then-mundane structures being built. At a grocery store, pictures of the grocer standing in front of the cramped corner space where his business got started back in New York City all those years ago. You know what I mean. If you look around you'll start seeing these, too. And I ask myself, who took these, and why? Were these as candid as they are meant to appear? How much of our photographic history as families and as communities relies on a couple of odd individuals who carry a camera everywhere and are willing to stop people to pose and say "you'll thank me in ten years"?
The ones that really get to me are the pictures from 50-100 years ago of ordinary city streets and scenes of nothing in particular. The kind of picture that I take while I'm out, then delete as soon as I get home because there's nothing interesting about it and nobody would ever care to see it and it's not worth the hard drive space or mental effort to sift through. And yet here I am, looking at just such a picture that someone else took a hundred years ago! If they had thrown it away — if every photographer were in the habit of throwing away all the boring negatives — we'd have no photos depicting the average way of life of entire generations of people. Once a boring picture passes the age of ten, twenty, fifty years, suddenly it stops being boring simply by virtue of age, but somebody had to be the diligent steward that preserved it for all that time — held on to a boring photo in faith that it would someday be not-boring. And lo, that day is here. Who preserved it? Who published it? Who noticed it and found it worthy of distribution? Why was it chosen, among all others, to reach me across such space and time?
When a big historical event like a riot or an attack or a coronation is going on, you've got a limited time to capture it. But to take a picture of an ordinary street on an ordinary day? I could take a thousand of those in twenty four hours if I wanted. I don't, because they would be lame. But someone else did fifty years ago and it's not lame. How easy it is to let an ordinary moment pass you by every day because it was always too ordinary to capture.
There is yet another source of dissonance within me. My favorite medium is video, not photo. I spend my time watching films and youtube. Sure I can name a few names like Adams and Leibovitz, but I don't actually care to look at their work. I have much more to say about Cronenberg and 张艺谋 and 김기덕. And Folding Ideas and Not Just Bikes and 3kliksphilip.
In this discussion of memories and the capturing of the mundane, I must share with you videos like 2:30 AM at 7-11 near Disney World and Final day at Glendora High School 1999 and kliksphilip's VHS digitisation. These are fascinating to me and make me feel guilty for not having anything like this from my own life. But if these people had shared albums of still photos instead of videos, I probably wouldn't have even come across them in the first place, and if I had I would have barely skimmed through. I mean, I can go on the internet and find photos from the 90s right now if I wanted to. But I won't. Because I don't care. But video makes me care.
This may seem to be in conflict with the previous point about old photos. However, I think I can resolve this by saying that old photos interest me because they spur me into thinking about how information and once-present history manages to make it through the great sieve of time. Old photos are a catalyst for a session of broad curiosity and reflection, and it is not really the particular photo or scene that matters to me. On the other hand, old videos interest me because they actually make me feel connected with the subjects and present in that moment, and I watch them intently. Stills don't do that, even the really old ones. The 7-11 video sticks in my memory in a way no still from that day would.
I write this blog, but I don't read anyone else's. I take my photos, but I don't look at anyone else's. I watch other people's videos and I don't make my own. What's going on here?
It is partially economical. Video files are stinking huge and I feel burdened with knowledge about bitrates and such. My camera can give me sixty four stills for a gigabyte, or about a minute of video. Which would I rather have? You know I'm trying to self-host this blog and all. I could compress it later with handbrake, but that adds time and a lot of steps to the process that would otherwise be "take pictures, copy pictures". That's the other inhibitor: effort. Producing a video, and certainly producing a cinematic work, is a lot more effort than sitting in a chair writing a blog article or walking around taking pictures. A single uninterrupted take usually does not make for an interesting video, one needs to edit. The audio from the camera body's built-in microphone is usually not very useable due to hand movement and button clicks, one needs offboard sound. One needs performative skills and contiguous blocks of free time. And it's even more nervewracking / embarrassing to film friends and family.
That's a lot of excuses. I am left with the fact that I produce work in mediums I don't consume from anybody else, and I consume work from everybody else in mediums I don't produce. I am not sure how to feel about that yet.
See also: https://internetkhole.com
See also: https://www.chronophoto.app/game.html
Here are a couple of technical details, and the techniques I'm currently using. This is being kept separate from the rest of the article because talking at great length about gear and settings is very easy for the author (me) and not very interesting for the reader (you, and future me).
For still lifes, I am using manual focus mode with a button bound to autofocus. I rarely need to adjust focus manually, but I find that "manual plus AF button" is more convenient than "AF-S plus AF-lock" when it comes to lock and recompose shooting. The main point being that I can let go of the shutter button without having to engage AF-lock, as you do in AF-S.
For moving subjects, I am using continuous 3x3 zone focus with face detect. However I've had quite a few focus misses with faces in the scene, so I'm still working on this.
For the time being, I'm living the SOOC lifestyle. I have made very minor levels adjustments on a few pictures and cloned out a few distracting branches, but otherwise I have not become interested in spending time in editing.
Everything looks good in telephoto. Even the best cell phones are still not up to par here, so people aren't used to seeing themselves in long focal lengths and it impresses them. In still lifes, it draws attention to geometry.
Everything looks good in black and white. It draws attention to shapes and textures and hides distractions. ISO noise can be passed off as film grain.
I like the Fuji X-T dials and would be happy to never touch a PASM dial again. I will be curious to see if my opinion on this changes.
I do not use the terms "full frame" or "crop sensor". I think it's silly that the 135 size has been crowned "full frame" when there are way, way larger formats out there. An APS-C or M4/3 sensor is not a cropped piece out of a larger sensor, it's just a smaller sensor.
Here's a 100% crop of a photo I took at 55mm focal length. The 1/f rule of thumb for shutter speed would suggest using 1/80 seconds as this is an APS-C sized sensor.
Actually, it was done at 1/18, since the sun was setting and ISO and aperture were already maxed out. That's one eighteenth of a second, handheld, and it's pretty darn clear as far as I'm concerned!
Maybe this isn't a surprise to you, but as soon as I took that shot I actually said out loud "somebody just did a great job and it wasn't me". I couldn't see those leaves' veins with my own eyes in that light. Modern cameras are amazingly good. Between OIS and automatic (P)rofessional exposure control, it's sometimes harder to take a bad picture than a nice one.
If there's a lesson to pull from here, it's that you should embrace the camera's fully automatic features and assists so you can spend your effort on composition and timing. Don't listen to anyone who looks down on you for using any kind of auto mode. There is no auto composition and that's worth more.
This is a lot of philosophizing from someone who's only had the camera for five months. My thoughts have been moving so rapidly I felt I needed to write some of them down. I probably will look back on this in three more months and find it unrecognizable.
If you're on the fence about buying a camera, I would recommend it. Some people will say that unless you're willing to spend more than a thousand dollars, you should just get a cell phone instead. But the 2008 Nikon D90 I brought to the renaissance faire can now be found for less than $200 with lens. I'm glad to have a better camera now, but it was enough to give me the kick I needed and might be enough for you.
Have fun.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>The road is not a squirrel's natural environment. The road is hostile to the squirrel, his life threatened whenever he steps onto it. It is a recent development, a recent intrusion into space that was previously green. The squirrel's ancestors were hunted by dogs and hawks, not cars. But he does not know this. Squirrels don't study history. They don't talk to each other about the past. They don't share recipes. A french fry might be traditional cuisine.
The timescale on which a road is built is incomprehensible to the squirrel. A road that opened the day before the squirrel was born is the same as a road aged fifty years; they're both part of the present environment and for the squirrel the present is all there is. They are as old as mountains. The age, size, and condition of the road do not affect the squirrel's priorities: food, water, shelter, mate. The road is only terrain.
The creatures which built the road are not up for communication. The squirrel is not prompted for input and does not attempt to provide any. They would not listen if he did. He defers to them and accepts the paving of the road like his ancestors deferred to nature and accepted the erosion of a river through rock, the upheaval of a landslide, the blast of a volcano. It can hardly be called acceptance, but it doesn't matter. The landscape is altered. The squirrel either adapts and dies later or doesn't and dies now.
The squirrel does not ponder the nature of existence, the injustice of time and death, or the worsening conditions to which he is subjected. He would not be much happier if he did. His challenges tomorrow cannot be lightened by remembering his leisures yesterday. The forces which build the roads are still active. So too are the rivers and the volcanoes. They operate on a higher plane, disconnected. The squirrel's actions will never change them. He can't even be a martyr. The squirrel continues gathering nuts.
The squirrel does not question the road. He does not ask why it exists. Neither does he question air or water or trees. Neither does he question dogs or hawks or rivers or landslides. It does not cross his mind to ask these things. They're just there. In nature there is life, death, food, danger, resource, scarcity. There are squirrels, dogs, people, trees, roads, hawks, cars, nuts, and busy intersections, all of which must be navigated to survive. The squirrel navigates. He seeks shelter today as he did ten million years ago. He avoids hawks. He seeks mates. He avoids cars. Much has changed. Nothing has changed. The road is a squirrel's natural environment.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I said from the beginning that gwern.net was a source of motivation for me to start writing, and I specifically linked to his article about archiving the URLs to which his blog links. It's time for me to start doing the same! I don't have quite as much to say but I thought it'd be worth documenting. Gwern just recently said he's working on a new system.
To preserve third-party pages, I use a browser extension called SingleFile. It saves the entire page into a single .html file by using data:
URIs to embed images and other resources. Then I just upload that file along with my own article and link to it. At the moment I am not very concerned about cloning entire websites — I just need one page at a time.
At first I was using web.archive.org to provide archive links, but now I prefer self-hosting SingleFile pages for a few reasons:
While I expect IA to be around for a while, my goal is to reduce dependency on third parties. In some ways, depending on IA as a single third party instead of numerous third parties is better; in some ways it's worse. A single point of trust is also a single point of failure.
IA does not give the reader an easy way to download the archived page for themselves. CTRL+S does not produce a good replica in most cases. With my SingleFile pages, you can just CTRL+S and get the exact same file that I have. My goal is to share information with you, so that's kind of important.
IA might receive a DMCA takedown request and lose the content. If I want to preserve the linked page I'll need to make my own copy of it anyway, so why do both IA plus SingleFile when I can just do the one?
IA is fairly slow to load. I mean no offense to them as they are a fantastic resource and I'm okay with them prioritizing capacity over speed, but it is true.
Sometimes I need to link to a newspaper or other blogger. These articles are often professionally written and need to be pasteurized for consumption by a sane audience. Hosting the HTML myself allows me to do this. Here's an article before (4.11 MB) and after (0.14 MB) I cleaned it up [1]. Oh, and that's with SingleFile's "remove scripts" option enabled. It was 9.75 MB with scripts and I don't want to waste either of our bandwidths by including that here. I shouldn't be too harsh on them, putting two dozen paragraphs of text into a document is really hard and doing it efficiently requires a great engineering team like mine.
For what it's worth, myself and others have noticed that a lot of news sites today are deathly afraid of including external links in their text — they'd rather provide a useless link to themselves than a useful link to a third party. I don't want to be like that, so I'll either include the original link alongside the archived one, or I'll edit the archived page to make its above-the-fold title a link back to the original URL.
[1] Base64 encoding of embedded resources makes them take up about a third more space, a tradeoff for the convenience of having it packed in a single html file. The original source for that article costs me about 3.7 MB over the wire.
I wrote my own linkchecker.py because for some reason I like writing my own solutions instead of using other people's. It gives me a report organized by HTTP status and domain. If the link has a problem, it tells me what article it's on.
It immediately found multiple problematic links, all of which were my fault. My engineering team dropped the ball on this because they were too focused on innovating new ways to put paragraphs into documents, but the linkchecker should reduce these incidents in the future.
Actually, it's a good thing if all the dead links are my fault, because I can easily fix it. As long as I continue making SingleFile archives, the majority of dead links I encounter should be resources that I renamed or images that I forgot to upload. I should be able to run it on a cronjob and use operatornotify to get emails about it, after I fine-tune the error / warning levels. I tend to link to a lot of youtube videos which, of course, I won't be rehosting here due to their large file size, but if it's a video I really care I'll have downloaded a copy to my personal computer and can find some way of getting it to you.
So, that's where we're at for now. If you see any other problems that I missed, you can send me an email.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>When I was a kid, one of the computer games I played was Night Light, by GTE Entertainment. It's about Pandora the cat and Pixel the dog exploring the house in the dark after all the people have gone out for the night.
This game stuck in my memory in the way that only a formative childhood game can. There is something about the game mechanic of using the mouse as a flashlight that's very appealing to me, though of course I don't know if this is cause or effect.
For the past several years, I have occasionally been reminded of the game and tried to search for it online, only to come up empty handed. Finally, in 2018, a youtuber named Vulnerose Plays did a playthrough and also uploaded the ISO to the Internet Archive. The majority of comments on that video are from other people saying they'd been searching high and low for the game, too [1].
At the time of this writing, I have not actually played the game using the provided iso, as it would require me to emulate an older version of Windows and I haven't gotten around to doing it yet. But, I recently had the inspiration to reproduce the basic mechanic using javascript canvas, and that brings us to today.
[1] spoiler alert, but there's a better copy here: https://archive.org/details/night-light_202208
I think some readers might be interested to know how I got the images out of the game without playing it, so I'll walk you through a bit of that here.
I used 7-zip to open the .iso file and browse the contents. Sometimes, you'll find that a game's assets are embedded into the .exe itself, and that makes things more difficult. Graciously, this game has the majority of its assets laid out in folders as separate files, which is great. It's not too hard to find a LIGHT.BMP and DARK.BMP for each level.
These images are 512x344, and they've got a hardcoded shadow underneath the game's HUD. But what are those megabyte-sized .mov files?
These video files contain 80 frames, each a tile of a larger image. I used ffmpeg to take the video frames apart, with ffmpeg -i DARK.MOV %03d.png
.
The first 16 frames can be stitched together in a 4x4 grid to produce a 1024x688 image, and the last 64 frames can be stitched 8x8 to produce a 2048x1376 image. It's quite astonishing to see these levels in such high resolution after all these years.
I deleted 01-16 from each folder, then updated my stitch.py to take a --grid
argument, and stitched the remaining 64 images together for each level.
I also extracted the audio clues and converted them to flac. Unfortunately, lots of the source files were corrupted, with an excess of zero bytes making them impossible to decode.
I wrote ffdecodetest.py to help me with this sort of task. The backyard and living room levels got particularly rekt, with only three and one clue passing the test, respectively.
When I originally published this article in April, the next sentence was:
If by some very lucky chance you have a copy of this CD, perhaps you could try re-ripping it for us.
And that's what happened!
I got an email from Josh Henderson who also has a CD of the game. He kindly extracted the ISO and uploaded it to archive.org: https://archive.org/details/night-light_202208
Thank you again Josh!
I popped this one open with 7-zip and got all 471 clues in mint condition.
So, all I had to do next was copy the canvas code I wrote last time and start shedding some light on things.
Double-click on each game to go fullscreen. Just to be clear, I haven't recreated any of the actual puzzle gameplay, I'm just demoing the flashlight mechanic.
Your browser might prevent the clue audios from playing if you haven't clicked on anything in the document yet. Now's a good time to click something. How about this:
I'm glad that the level images were easy to extract, since those were the most important parts for me. I'm also glad we recovered all of the clues. However, I really would like to get the main menu images and the staff credit portraits out as well.
I looked through all the files with 7z, expecting to find a .bmp or a tiled .mov representing the menu, and I'm simply stumped. I don't see them anywhere. The closest thing I could find was MMCHOICE.MOV, where Pixel and Pandora discuss the level options, but it's cropped in on them.
The game uses this kind of video file as an overlay whenever it needs to put the talking characters in front of the game. If you look through the QTPUZZLE folder you'll find many more of these.
So, it's not like mmchoice.mov is damaged, or cropped accidentally. But, like the puzzles, I expect to find the loading screen, the main menu art, and the credits photos in their own files. I just don't see any more tiled movs or bitmaps. There are 18 .pic files, but those are just BACKMASK.PIC, FOREMASK.PIC, and a set of LIGHT.PIC and DARK.PIC for each of the eight levels.
Perhaps I simply missed something, or perhaps they are embedded somewhere else, though I don't know why that would be. The game's NIGHTMPC.EXE is 7.7 MB, which seems big enough to hold some secrets. I searched through the binary for BMP and MOV headers but didn't have any luck, and 7-zip doesn't open it the way it does with some executables.
My understanding is that the game is supposed to work on both Windows and Mac: many of the game resources are provided in duplicate (BMP/PIC, WAV/AIF), but as far as binaries go I only see exe. What's up with that?
If you discover anything, send me an email!
Along the way, I also found these image masks which give a hint as to how some of the click detection was done, which I think is very clever. Each of these cells has a unique RGB color — so the programmers could make each color represent a choice for the user to click on.
If you watch Tom Scott, you may have seen his video about Need for Speed, a sentimental visit to the real life location after which a level from the game was modeled.
All the things that we create, whether you have a big audience or whether you're just making stuff for the folks close to you, sure, maybe those things you make will be forgotten. Or maybe those things you create will get laid down as someone's long term memory, and affect them a lot later in their life. So, make nice things. Try to give people something they'll be nostalgic about. You never know what impressions you might be making for the future.
A kind thank you to all of these people:
Have fun!
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Note: this article will make more sense if you are using a mouse or other pointing device. Requires javascript.
Warning: things can get a little spooky in the dark!
You can read the source code for this document here (or by pressing Ctrl+U in chrome / firefox).
I really like the "dark mode" switch on https://tonsky.me [1]. It's a fun subversion of expectations and reminds me of Night Light (1995), a PC game for kids about using a flashlight in the dark.
One of the splash texts I put on my homepage a while back says "looks better in black and white". Yesterday, while hypnotized by my own pulsating creation [2], I had the idea to put the two together and create a grayscale "flashlight", or perhaps a lens. I learned that the CSS property mix-blend-mode
allows me to make a div that turns everything below it gray. The other mix-blend-mode options are cool too.
The results don't look exactly like a light source, but it's a nice toy. Here are some different flashlights and photos with which to admire them:
It applies to all elements on the page. sample sample sample sample sample.
♫ It's just your imagination
♫ night time fascination
I think those effects are fun, but they don't really give you the feeling of being in the dark like tonsky's flashlight switch. His works by setting the background color to black, so all the black text "disappears" even though it's still there. I wanted to come up with a flashlight that really works for all elements on the page, but I couldn't figure it out with CSS.
Instead, I was able to get a basic flashlight effect working with canvas by covering the entire screen in a black rectangle, and punching a hole in it.
If at any time you need to come back, all you must do is open your eyes.
This works great in conjunction with the mix-blend-mode lights:
Go back up and look at the images again!
After posting this article to Hacker News, I got some great suggestions for solving this problem with CSS:
body
{
clip-path: circle(80px at var(--lightx) var(--lighty));
}
alternatively:
#blackout
{
position: fixed;
z-index: 1;
inset: -5px;
background: radial-gradient(circle at var(--lightx) var(--lighty), transparent 0, transparent 100px, black 110px);
pointer-events: none;
}
where lightx and lighty are set by a mousemove handler. I haven't assessed the performance impact of the Canvas solution versus these CSS solutions, but if I need to do this again in the future I think I will preferentially reach for the CSS version since it fits well with my usual way of doing things.
I also wanted to try making a Night Light game effect. The player who recorded the above video also uploaded the game .iso to the Internet Archive. Thank you Vulnerose!
https://archive.org/details/NightLight_201809
I was able to open the iso in 7-zip, extract the level artwork as bmp files, produce the toy below. I've made a followup article with the other assets.
I first tried to approach it with mix-blend-mode, but I don't think you can use those effects to produce arbitrary image masks. I got it done with a more traditional method of translating a background-image property. The only jank fix I'm not really happy about is the background-size property for the flashlight layer, which I had to set using px values in javascript to match the rendered size of the parent. All the other background-size options created ill effects when I wanted to change the size of the flashlight to anything other than 100%. But I'm not that good with CSS and there might be a better answer.
Please turn off your flashlight first. Or don't, and enjoy the two effects together!
And, I couldn't help it:
The background-image version of Night Light works okay, but the revealed image is sometimes a few pixels out of alignment, which weakens the illusion. This depends on how much you've resized your browser and is especially noticeable with the vertical lines on the "close out sale" window.
This was a good opportunity for me to get practice with canvas, and I find the results look a lot smoother, so here's the same game again.
Have fun!
[1] Archived here in case it gets changed.
[2] A little vanity goes a long way!
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>You can listen to this article. FLAC, about 350 MiB. Download.
Every once in a while, someone will ask me "have you seen that commercial about..." and my response is almost always "no". I haven't seen that commercial. I do my best to not see any commercials.
Throughout this article I will use the term "adblock" as a common noun, not a proper noun. I am not referring to any particular adblocker and certainly not the one by the name of Adblock or Adblock Plus. Today, uBlock Origin is widely accepted as the best adblocker, but this will of course change with time. This article contains some external links. Make sure to install an adblocker before clicking on any of them.
I will mostly be talking about advertising over the internet, because that's the medium where I have the most knowledge and experience. I don't watch TV or listen to the radio. There are too many ads there.
The URL for this article is advertixing
because when it was called advertising
, the inlined images were being adblocked by /advertising/*
URL pattern matchers. Ha.
This article has been a work in progress for a very long time, so some references to supposedly current events may seem a bit temporally challenged.
In some sections of this article, I criticize the advertisers who create ads, and in others I criticize the publishers who publish those ads in exchange for money. The incentives and issues surrounding each are different and I'll try to make it clear which one I'm referring to, but in my blind rage I'm sure I'll switch topics without mentioning it. Let's start by defining what we're dealing with.
I find that advertisements can be separated into three broad categories by their mode of propagation:
Sponsorship, in which a product seller pays a publisher to publish ads about their product. This is a very traditional and straightforward kind of ad.
This includes the ads you see on TV, radio, magazines, newspapers, web sidebars, headers, popups, in apps, as product placement, and as bloatware. This does not include first-party upsells or encouragements to upgrade to the premium edition of something you already have.
Sponsorship advertisements might be explicitly labeled, or they might be hidden amongst regular content so that you don't realize you're being advertised to. The second is more lucrative though FTC regulations against them exist.
Spam, in which a product seller self-publishes ads for their product in spaces where ads don't belong [1] and without getting permission from the owner of the space.
This includes uninvited email and phone calls and private messages, self-promotional forum posts, SEO keyword abuse, fliers stuck under your windshield wipers, door-to-door salesmen, and solicitors outside grocery stores.
Colloquially, one might include first-party upsells, because they're annoying and feel like spam, but I think it depends whether they intrude into your personal space, such as a spam email appearing in your inbox, or occur within the first-party's space, such as a banner on their webpage. You are allowed to always hate upsells but that doesn't mean they are always spam.
Most spammers are cowards. They won't own up to their actions. They'll say "I'm not spamming, I'm just letting you know about this cool new thing".
Chumps, publishers who discuss a product and give it ad-like publicity without compensation from the seller because they think they can use it to attract an audience of their own, usually because the product is currently a hot topic. This is different from word of mouth because the chump isn't actually passionate about the product, and may not even have it. The chump probably gets their income from other sponsors unrelated to the product in question, or by selling their own product.
This includes bloggers, reviewers, and opinionators discussing new products, press releases, scandals, speculation, leaks, and hype. Product sellers can intentionally create scandals or leaks to get free advertising from chumps. Check out this MKBHD video where he calls out chump media outlets giving free attention to a certain scandalous device, which I am now ironically propagating by showing it to you. inb4 MKBHD also speculates. Chumps will often regurgitate basic product information instead of forming their own opinions. Also keep an eye out for product reviews released too quickly after the product's launch, which indicates it was an embargoed job or the reviewer simply spent no time with it.
I feel that I need to give a concrete example of chumping to make my definition clear, so I'll continue with MKBHD because I can still positively say that I respect his work and I watch what he makes [2]. He releases lots of videos after spending only a week with a product, and the release of the video is often clearly aligned with an embargo. This means the company has sent its products to many different reviewers and told them not to publish their reviews until a certain date. So, the review doesn't come from a place of genuine personal interest in the product; the companies are using him as part of their scheduled marketing. These products attract viewers to his channel because they are new and hot, but he isn't getting paid cash by the likes of Samsung (probably) — he performs ad segments for other sponsors. The end result is that the viewer is being double-advertised to: they get to hear the product's basic specsheet read aloud to them with only superficial opinionation, then hear from another sponsor on top of that.
Sellers are incentivized to put chumps on embargoes because a single, big wave of marketing that gets everybody talking is more effective than the slow trickle that would come from reviewers finishing their work over weeks and months. Chumps are incentivized to participate in embargoes because if they miss the wave, the audience will have already had their fill of hearing about that product.
Rushing a review to meet the embargo deadline is one thing, but the chumps who do "breakdowns" of press releases, advertisements, and marketing copy are undoubtedly on an even lower rung.
The majority of this article deals with sponsorship advertisements because they are the most systemically accepted of the three. Consider:
There's as not much to say about spam. Everybody already hates spam. This article is about systemic problems with advertisements and spam is built upon the abuse of systems by definition. Discussing the problems with spam is like discussing the problems with homicide. It's not systemically accepted but occurs anyway. Spam will exist as long as there's two people left on the planet popular systems and spaces exist. Spam can only be countered with diligent policing by the owner of the space, or by convincing the spammer to repent. Good luck with that. Sponsorship, on the other hand, exists comfortably within the system. I dedicate one section of this article to spam but otherwise I don't have much to say about spam except that I hate it too.
Chumps usually rely on sponsorships to do what they do. There is not much need for me to discuss chumps because if we could eliminate sponsorships, we'd bring the majority of chumps down at the same time. By my definition, chumps are not actually interested in the product, they only talk about it to get attention, clicks, and ad views. Without sponsorships to make chumping worthwhile, most chumps would quit. Only those who sell their own product would continue, and I believe that to be a minority.
As such, of these three kinds of advertisements, sponsorships are the ones that I find most worth writing about.
Glossary:
[1] as if they belong anywhere amirite
[2] This paragraph applies to the majority of hot-topic reviewers, I just don't watch very many of them. I like that MKBHD does get into industry critique and Youtube critique from time to time, but I'm sure the chump videos are better at paying the bills.
Capitalism is a complicated topic. The core principles are pretty simple and don't sound inherently malicious, at least to me. Sellers try to sell for the highest price they can, buyers try to buy for the lowest, and everybody either strikes a deal they're satisfied with or goes home empty-handed. Beyond the essentials of food, water, and shelter, the human as animal doesn't technically need very much, and the worst that can happen in most transactions is disappointment.
Sellers do research to learn buying habits, buyers do research to learn of alternative sellers and price points. Sellers don't necessarily need to have the absolute highest quality product on the market, they just need to hit a good quality-per-price ratio, or value, to accommodate different segments of the market: some buyers are professionals who need the best quality tools and will pay a lot for them, other buyers just need something that works well enough.
When a person decides to start selling products, they start from a position where nobody else knows they exist. Sellers advertise so that they can enter the buyer's decision-making process, and if they're better than the competition they'll rightfully win the sale. Competition drives sellers to innovate, lest they stagnate and be undercut or outperformed by new sellers. The result is a continuous progression of higher quality products at lower prices, and a steady churn of advertising along the way.
If I lived in the era where advertisements were barely more than hand-painted signs like "Visit Farmer John's farm for some tasty corn", I wouldn't mind them very much. It's fair to say that if Farmer John didn't make the sign, I might not know I could buy corn from him. His corn may in fact be the best in town, so I'll be glad to have learned of it. When I watch movies or see pictures of the wild west, with towns popping up along unpaved roads, I am sometimes jealous of how simple their economy seems. They weren't blasted with advertisements over radio and television and the internet, they heard from their neighbors and whoever came through town.
Then again, this is exactly when snake oil entered our vernacular, so now I'm doubting myself about that!
Indeed, it seems that these basics of capitalism do "work", in the sense that right now I can buy a computerized internet-connected device with only a day's wage, which is truly a feat of humanity. Products improve and prices drop. So although I hate advertisements as they exist today, it's hard for me to say that the deepest, fundamental notion of advertising is inherently malicious. It is not wrong for a furniture maker to want to sell his furniture, I don't think.
You can consider this article to be a Capitalism sequel to my Insurance article: the primordial elements of Capitalism seem reasonable, but the current state of affairs is objectionable. Maybe there is a level at which advertising can be called a force for good. But things change when we reach the scale of multi-billion dollar global companies and their ads, and they've ruined it for everyone.
According to the basic principles of capitalism, sellers should try to sell high quality products because the only way to get the money out of the customer's pocket is to have the best quality-per-price ratio on the market. Capitalist competition is grounded in this. When a company makes its money through goods-for-money transactions, we'd expect them to try making a good product.
But that's hard :(
What if you could just skip the customers? What if the money could come from somewhere besides the customer? By displaying a sponsor's advertisement alongside your product, you can earn more money without having to make your product better. You might be able to reduce the price of your product to attract a wider range of customers, netting overall higher sales. If the sponsor pays you enough, you might even be able to offer the product to the customer for the irresistible price of free. And if it's free, then the quality-per-price ratio becomes a division by zero and the fundamentals of capitalism implode. Suddenly, all levels of quality are functionally equivalent. The quality of the product is now irrelevant, detached from the means of income.
If the product seller wants to increase their income, increasing the quality of the product won't help anymore. All they can do is try to show the sponsor's ads to more and more people. That means the seller has just pivoted their entire business model away from creating their actual product towards reaching more eyeballs. This shift is much bigger than most realize — reaching eyeballs is an entire industry of its own: it's called the media. Whatever you thought your business was can go right out the window, because you're a media production house now and you're competing with the likes of Hollywood in the quest to reach more eyeballs.
You might be thinking that the quality of the product still comes into play because if two competing products are both free-with-ads, the customerbase will still gravitate towards the better one, thus rewarding it with more sponsorship money and longevity. The end result could be just as if the customers had paid for it themselves, just using their eyeballs instead of their wallets.
There are some cases where this doesn't work at all because of network effects or surrounding ecosystems. Users don't want to join the most technically superior social network, because their friends are on the old one. Users don't want to switch to the most technically superior spreadsheet tool, because there are lots of video tutorials about the old one.
There are other cases where it does work — but only briefly — because the better product is coming from a young and idealistic company that hasn't fully realized the consequences of their recent pivot into the media production industry. Young companies, especially those with angel investors, can undercut the incumbents because they're willing to operate at a loss in an attempt to fast-track their market share. But when it comes time for them to start returning on their investments, they realize they need to start recouping their costs via sponsorships and they become just like the incumbents they destroyed. See how imgur.com took over the image hosting space with their easy UI and straightforward hotlinking. Now, they are "Your upload will resume after this ad, or press ESC", impossible to visit hotlinks without getting redirected to the webpage, pushing you to download the app. Like ImageShack before it, Imgur has gone downhill and is ready to be replaced by a new starry-eyed image host destined to repeat the process. Some day, Imgur will die, and its in wake will be millions of image links that no longer work. Free-with-ads products live on a treadmill and the entire internet suffers for it. If there's anything on the internet that you might want to access again in ten years, I'd suggest you buy a nice big hard drive and start downloading it now while you can.
Goodhart's Law says "When a measure becomes a target, it ceases to be a good measure". We've all seen this: people who split one task into many small ones so they can say they did many tasks; students who increase the font size on their essay so they can hit the minimum page requirement more easily; programmers who close bug reports without fixing them to keep the issue count low; Youtubers who fluff up empty ideas into 10+ minute videos for algorithm favorance; entrepreneurs who cash in on dead-cobra bounties by breeding more cobras to kill, or, rather, 3D-printing gun parts to sell at buybacks. People in general are very adept at exploiting these kinds of opportunities and, as game theory will tell you, it'd be silly not to.
See cost per impression (CPI). An Impression is when a person sees an advertisement, and the CPI is the dollar amount the sponsor pays the publisher for those. And you better believe that for the publishers, increasing impressions can easily become the top — or only — priority. Every day, the publisher has to choose between improving its product or finding new ways to reach eyeballs for its sponsors. One of these has direct financial incentive and the other doesn't. In order to increase the number of impressions, the publisher must increase page visits, video views, minutes spent on site, density of advertisement amongst regular content, etc. Attention is turned towards questions like:
The answers to these questions are usually along the lines of:
It doesn't matter if you're enjoying yourself or hating every minute of it, just as long as it's a lot of minutes. This is the origin of clickbait.
Businesses love to willingly fall into the Goodhart trap of maximizing engagement and eyeball reachitude because they love seeing pretty graphs that climb every quarter. The other metrics — the ones that are hard to graph — get ignored. Metrics like:
I will reiterate because it is so important: when a product is free with ads, the fundamental rules of seller competition under capitalism are subverted. The need for a quality product becomes zero, replaced by a need to drive impressions at the cost of anything else.
The software industry is notable for its focus on metrics since it's so much easier to track digital actions than real-life actions [3], thus metrics are much easier to collect and deify. This is to the detriment of product quality and long term consistency. Engineers (or their bosses) will pick some specific metric to optimize, beat the hell out of it, and pat themselves on the back until— Wait!, look over there!, we should be optimizing for this other specific metric instead! Look over there!, Apple is doing it this way now! At every step of the way there is a delusion of climbing towards some peak quality or efficiency, when actually it's just going up and down a bunch of separate peaks in a mountain range. I wonder how much is deliberate by engineers who want to stick it to their dumb managers and get a fat paycheck for essentially wasting time, and how much is really, earnestly believed internally. Either way, the user is the guinea pig who has to deal with a product that continues to change and re-prioritize for no good reason.
[3] At least until face and gait recognition in store security cameras become universal.
We would all like to think that we're immune to the manipulative effects of advertising. That we make our buying decisions only after comparing our options and coming to the best conclusions. That we can see right through the doctored footage, fake food, irrelevant celebrity endorsements, industry buzzwords, and hopelessly incompetent baboon actors.
What's the longest you've ever spent thinking about a purchase before making it? Try to remember a time when you wanted to buy the most perfect option that would match your needs exactly. Maybe it was a cell phone, or vehicle, or mirrorless camera, or pair of hiking boots. Remember how many searches you did, how many alternatives you compared, how you divided the price by your hourly wage to get a feel for how many work-hours you were about to trade for that item. How many hours of research did you do? One or two? Five or ten? You could answer 100, and I'd believe you.
It doesn't matter, because every single marketer and salesperson who works for the company that sold you the item puts in 8 hours a day, every single day, trying to sell it. Buying products is what you do in your time off. Selling products is what they do for a living. Multiply that by the number of staff on their marketing department and immediately it's clear you're up against quite a force. And this was the exceptional example — what about the other 99% of purchases that you make in life which don't receive even a fraction of that research time? This imbalance of effort is a good first hint that individuals can't expect their buying decisions to ever be perfectly well-informed.
As a buyer, I need to juggle the pros and cons of a million different aspects of a million different products at a million different price points and find where they converge. For every technical detail that I can devote a few minutes or hours of research to, there is someone whose livelihood it is to understand that detail and find the right way to sell it. How should I feel about GMO food? Does "cage free" necessarily mean the animal is treated well or not? Does this unlocked cell phone support the cellular bands I need for my carrier? What's the difference between all these space heaters? What's the relationship between megapixels, sensor size, and f-numbers? Do I want more cores or more gigahertz? How many plies do I want in my toilet paper? What the lux is a lumen anyway? Is 4k always better than 1080p? How do I know this hard drive isn't secretly SMR? My buying energy is spread graphene-thin, but a company's marketing department can focus entirely on selling their product.
Some people are rich enough to have a personal butler wherever they go. But how about a personal psychologist-butler, who can tell you about all the ways the people you interact with are taking advantage of your natural thought processes? Your psychobutler could say Pardon me, Sir/Madam, may I inform you that the small, medium, and large sodas are so close in price so that you focus on the relative deal and not realize it's a total racket no matter what you pick? If I may interrupt, Sir/Madam, the colors used in ads are carefully chosen to push you in the right direction based on research correlating color with emotional response [4]. Salesmen encourage feelings of urgency with their buy now! last chance! one day only! messaging to prevent you from calmly measuring the sale. Items are priced as $XX.99 so that you mentally round it to $XX.00 instead of $XY.00. The milk is at the back of the store so that you pass by everything else on your way there. Thumbnails with faces, and especially surprised expressions, pique the most interest and clicks. Ads show crowds of people to help induce FOMO and peer pressure. The free continental breakfast is paid for by the cost of your room. Businesses sell coupon packets where the savings is greater than the cost of the packet, but they make you feel obligated to visit more often to use them up, spending more money than you would have without them [5].
Do you have a personal psychobutler? The advertisers do. Teams of them. All working around the clock to find the optimal way to disrespect your decision-making autonomy, because you're an ape with an ape brain and you can be tricked.
I've reached the point that I no longer question business decisions any more. Sometimes I'll see a product that looks stupid, and in the past I would have said "that's stupid, why would they do it like that?". Now, I think "that's stupid, but I guess they think it'll make more money", because that's always the answer. I certainly still spend a lot of time criticizing business decisions, but not questioning them.
That's not to say all companies are perfectly rational, for they too are made of apes. There's quite a bit of cargo-culting and trend-following. Apple removed the headphone jack? Oh my god, we'll look so behind if we don't remove it too! [6] I've given up on thinking that big companies ever intentionally make anything good [7]. That's just a byproduct when quality accidentally coincides with profit.
As they say, you need to know your limits. I for one recognize that no matter how smart I think I am [8], I do not have the capacity to compete with the behemoth that is modern marketing. I recognize that advertising can influence me even if I don't feel it and can't articulate how. I cannot understand the intricate details of every product well enough to counteract the positive spin that advertisements will always try to place on them.
As such, I am better off cutting advertising out of my life as much as possible, rather than lying to myself that I'm immune. And you are too. People like to think they're not influenced by ads, but if that was true then surely the companies would have given up on making them by now. The industry is foolish, but not that foolish. Avoiding ads doesn't suddenly give me an infinite amount of time to research before buying, but it helps me to start my research from a more objective standpoint rather than being primed by ads.
Hacker News user ineedasername shared his thoughts on some mobile game advertisements:
Cunningham's Law states "the best way to get the right answer on the internet is not to ask a question; it's to post the wrong answer."
A sort of interesting "corollary" to this is something I've noticed in mobile games with in-app ads for other mobile games:
The best way to attract a player isn't by showing them someone playing well, it's by showing them someone playing very bad.
Because these ads show demo play (usually of puzzles) where the player is making obviously bad decisions, and watching it is sort of like seeing a dozen objects in a row, but one of them is completely askew, and there's an urge to straighten in out a bit.
I only noticed this after seeing a bunch of ads recently for perhaps a dozen different games, and realized that I felt somewhat uneasy when they came on instead of simply impatient, and eventually. I tracked this feeling down to the crappy gameplay phenomenon. And once I realized that was the issue, the unease went away.
Further reflection made me realize I'd been much more tempted to download those games to "do it right" than other random games that didn't seem to use this tactic. It was actually when I broke and was about to download one that I had the realization, basically "this game looks awful and tedious, why am I about to download it?"
macksd shares his children's reaction to TV commercials:
We went quite a few years without ever seeing cable. My kids would stream shows and consume other media on-demand, but any advertising was minimal and fairly non-intrusive. And then they were watching a kids show at a hotel once and the ads came on and the effect it had on them was crazy. They suddenly desperately needed all the toys in the commercials and were repeating catch phrases from ads after only seeing them a couple of times. The contrast in their behavior was insane. And they HAD to keep watching it like I hadn't seen before.
David Foster Wallace comments on advertisements that make fun of advertisements:
Isuzu Inc. hit pay dirt with its series of "Joe Isuzu" spots, featuring an oily, Satanic-looking salesman who told whoppers about Isuzus' genuine llama-skin upholstery and ability to run on tap water. Though the ads rarely said much of anything about why Isuzus are in fact good cars, sales and awards accrued. The ads succeeded as parodies of how oily and Satanic car commercials are. They invited viewers to congratulate Isuzu ads for being ironic, to congratulate themselves for getting the joke, and to congratulate Isuzu Inc. for being "fearless" and "irreverent" enough to acknowledge that car ads are ridiculous and that the Audience is dumb to believe them. The ads invite the lone viewer to drive an Isuzu as some sort of anti-advertising statement. The ads successfully associate Isuzu-purchase with fearlessness and irreverence and the capacity to see through deception.
Please do yourself a favor and read E unibus pluram in its entirety!
[4] Don't forget to enable grayscale mode on your phone or computer. Look for something along the lines of Settings > Accessibility > Vision > Grayscale, or Settings > Ease of Access > Color Filters > Grayscale.
[5] Some of you are probably shaking your head at my exasperated presentation of this paragraph. This is Marketing 101 level stuff, everyone knows it, stop sounding so dramatic. So why does it still work on people!
[6] For posterity, here's Samsung's ad mocking Apple for removing the headphone jack, shortly before they removed theirs too.
[7] I realize this is a No True Scotsman. Any company that does make anything good is simply "not big enough yet".
[8] very
[9] Notice that Joe Isuzu fires the whole bullet. That's 65% more bullet per bullet.
When a publisher puts ads on their website, how should they get paid? Is it enough to tell their sponsor "we had X,000 visitors who spent YY,000 minutes on the site"? The sponsor is unlikely to trust like that. The reality of web advertising is that the publisher will have to include a javascript package served by the advertiser so that the advertiser can see for themselves how many impressions they're making. We affectionately refer to these as "trackers" while we block them and curse their existence.
When two different websites use the same advertising package — take Google AdSense for example — then the advertiser Google will know that you visited both sites. So although each individual website cannot follow you around the internet on their own, they can aid Google in doing so by linking AdSense to their page. The more websites that use AdSense, the more eyes Google will have into your life, your browsing habits, your interests, your race and gender and sexuality, your purchases, your political affiliations. Like if every time you went to visit a friend's house, you found that some other dude with a clipboard had also been invited.
The vague concept of web tracking has become widely known in the past few years, but I think the specifics of how it works have not. Let's make this perfectly clear: the only reason advertisers are able to follow you around the internet is because all of the websites you visit are inviting them in. You are on a daily basis being betrayed by almost everyone who has even the slightest financial incentive to betray you. They will sell you off for a single cent, because $0.01 is bigger than $0.00. Why do you tolerate this? When Google tracks you, you must blame more than just Google, you must blame every single webpage that invited Google into the session.
In 2018, the GDPR went into effect. The General Data Protection Regulation, from the European Union, is a set of rules and regulations surrounding user privacy on the internet, and the storage of personally identifying information by website operators. Although the GDPR is an EU regulation, the effects are felt internationally since most companies want the opportunity to do business in as many markets as they can. Compliance with the GDPR means, for example:
And that brings us to cookies. Of the GDPR's effects, the rise of the "cookie banner" is certainly the most prominent and recognizable by the average person even if they don't know its background.
Cookies are small pieces of information that the website sends to your computer, and asks your computer to hold on to, so that it can recognize you next time you come back. The cookie is your way of saying "hey, it's me again" and have long been used to maintain account logins, settings, and shopping carts. Cookies are very helpful.
They have also been used for tracking and advertising. When a publisher invites an advertiser's javascript package onto their webpage, that javascript package will leave behind cookies so that when I leave website1.com and go to website2.com, the advertiser can see that I am the same person. By correlating my various interests with statistics from the rest of their tracked population, they can decide what type of advertisement is most likely to convince me to buy their product, and show me that one.
The GDPR did not invent the cookie, nor did it invent tracking, but by requiring websites to disclose the fact that the user is being tracked, it essentially invented the cookie banner. Six years down the road, I'm sick of cookie banners, you're sick of cookie banners, and we're all sick of the cutesy cookie graphics they put on them.
You will have noticed that a large percentage of cookie banners out there have one great big button for "accept all", because this is the advertiser's preferred choice; and another, smaller, less contrasty and less prominent button for "customize" or "configure". And that the even the customization menu is loaded with dark patterns and guilt-trip language like "we're using cookies to improve your experience".
Don't you wish cookie banners would just go away already? Oh, but wait, we never actually needed them in the first place:
Strictly necessary cookies — These cookies are essential for you to browse the website and use its features, such as accessing secure areas of the site. Cookies that allow web shops to hold your items in your cart while you are shopping online are an example of strictly necessary cookies. These cookies will generally be first-party session cookies. While it is not required to obtain consent for these cookies, what they do and why they are necessary should be explained to the user.
The GDPR does not require the user to be prompted for cookies that are necessary for the website to work. Let that sink in for a moment. Every single cookie banner you've encountered since 2018 has been a self-admission of nonessential tracking and advertising by the operator, standing between you and the actual reason you went to the website in the first place, because their opportunity to make $0.01 was more important than producing a site or publication that is pleasant to read and use. Didn't you say you're doing this to improve my experience?
And whenever you see a cookie banner that starts with the phrase "Because we respect your right to privacy, ...", just remember that they don't actually respect you enough to stop sending you trackers. That would just be too easy. They'd rather moan and whine about how the GDPR forced their hand into adding this big annoying cookie banner and there was just no other way, we're so sorry you have to deal with it. Indeed, these kinds of cookie banners can be considered a form of malicious compliance — if the website can convince you that a banner is required for all forms of cookies and that the law is to blame, they can sway public opinion against the legislature. The big bad government is the one ruining your web browsing experience, not us. Contact your representatives and get them to repeal GDPR so we can go back to sending you all of our trackers without telling you, the way it used to be.
If the user declines the tracking cookies, you can punish them by showing them the banner every time they come back, until they give up and accept (or block the element with their adblocker). If you wanted the "don't show me the banner again" cookie to persist, you should have enabled cookies! Bwahahahahaha.
Ok, that's enough about cookies. If you're interested in the topic of targeted advertising, you've probably already heard the apocryphal story about, appropriately, Target inadvertently outing a young pregnant girl by sending maternity-related coupons to the family's home:
"My daughter got this in the mail!" he said. "She's still in high school, and you're sending her coupons for baby clothes and cribs? Are you trying to encourage her to get pregnant?"
The manager didn't have any idea what the man was talking about. He looked at the mailer. Sure enough, it was addressed to the man's daughter and contained advertisements for maternity clothing, nursery furniture and pictures of smiling infants. The manager apologized and then called a few days later to apologize again.
On the phone, though, the father was somewhat abashed. "I had a talk with my daughter," he said. "It turns out there's been some activities in my house I haven't been completely aware of. She's due in August. I owe you an apology."
Like an Aesop fable for the ethically bankrupt, the moral of the story is given here:
We started mixing in all these ads for things we knew pregnant women would never buy, so the baby ads looked random.
As long as a pregnant woman thinks she hasn't been spied on, she'll use the coupons.
I think the Target story is fake, or greatly enhanced, but nevertheless it has become extremely well known. It has surely sparked the imagination of many an advertiser and thus contributes to the advertising landscape today. Any competent advertiser who is accurately tracking you will be sure to recover their plausible deniability by adding noise, thanks in part to this story.
Why do I think the Target story may be false?
The article cites "an employee who participated in the conversation", so nobody was willing to put their name on these quotes, giving the author free reign to embellish. The tidy plotline and the father's eloquent speech sound like the conceit of an author, though oddly they forgot to mention that he received a round of applause and $100 for his humility.
Even if the coupon packets were distributed at random, they're bound to hit this kind of situation at least once with an audience of Target's size. This is a typical statistical "surprise" [10].
Despite the nonstop development of advertising and machine learning in the years since, this story from 2012 still comes up as the first and often only example of eerily-accurate targeted ads. That would lead me to believe that either the intelligent ads industry hasn't advanced very far since then, or else has advanced so far as to become undetectable with no intermediary standout headlines — every other advertiser instantly skipped to a higher level of competence. The whole "cat food" thing came close but I don't think the evidence was very good. Here's a comment by Hacker News user segfaultbuserr:
Amazon is a $250 billion dollar company that reacts to you buying a vacuum by going THIS GUY LOVES BUYING VACUUMS HERE ARE SOME MORE VACUUMS
https://twitter.com/kibblesmith/status/724817086309142529
Everyone thinks this problem is really annoying, but to me it's a good sign - it indicates the current technical capabilities on using and abusing personal information is still limited, the predicted machine learning apocalypse is not here yet. In other words: despite the large quantity of personal information collected by advertisers, they still cannot exploit it efficiently enough, so far all they can do mostly is showing you the same things over and over
But maybe that's all part of a larger plot:
Let's say you buy a washing machine on Amazon. You're not likely to need more than one. Amazon knows whether you canceled or returned your order.
So the only way it makes any sense is if Amazon is advertising on the chance that you're going to cancel or return it in the future. Amazon certainly has those numbers. But do you think the chance you're going to cancel or return it is so high Amazon should advertise the same product to you instead of something else you might buy?
In data science, it is common wisdom to collect as much data as you can while you have the chance and filter it down later, because if you don't collect it now you might regret it. A political surveyor could ask you what state you live in so that they can make state-by-state comparisons, but it makes more sense for them to also ask about your city, so they can make intra-state comparisons from the same survey data instead of having to go out and do another survey.
This principle of data collection should not be considered slimy in and of itself. It is simply pragmatic, and applies to all areas: professional photographers tell their cameras to store raw sensor data instead of jpegs because their editing software can make better changes when it has the raw light and color information, and they can't go back in time to capture that moment again.
The problem is that advertisers haven't really figured out how to deliver on the whole well-targeted ads premise yet, but they're storing absolutely everything they can so they'll be ready for the algorithmic breakthrough if and when it comes. They're like pathological hoarders who keep every single paperclip because "it might come in handy someday", except the paperclip is your mother's maiden name and place of birth.
So if you think targeted advertisements are already accurate beyond detection and advertisers are magic-bulletting the population, you have cause for upset. And if you think targeted advertisements are still "buy more vacuums"-level useless, then that means that despite collecting the private details of billions of people's lives over several years, the advertising industry is too pathetically incompetent to make anything of it and is clearly unfit for the responsibility of handling such data in the first place, and you have cause for upset. Get upset!
[10] When you pick a random number between one and one million, do you think it feels lucky?
The Jevons paradox is when an increase of efficiency leads to an increase of consumption that outweighs the savings. Jevons's original description was of coal: as coal-fired steam engines became more efficient, producing more useful power per weight of coal burned, more people began using the engines and the total consumption of coal went up instead of down. Of course, those engines were used to perform work, so the Jevons paradox does not imply that the consumption is not productive in some way — each individual engine owner would say that the new engines had saved them coal — but the fact remains that the total usage of coal was higher than before.
One of the things we learn from the Jevons paradox is that we are restless creatures, and we are not satisfied with our consumption until we find ourselves bumping into limits. There is much to say about this topic both economically and ecologically, but let's get on to the part about ads.
When the internet was young, data rates were slow. It took minutes to send a megabyte. Most people won't wait minutes to read a webpage, so webpages had to be kilobytes. As internet speeds have gotten faster and faster, the efficiency of bytes transferred per second has increased, and so too has our consumption. Maciej Cegłowski gave a talk called The Website Obesity Crisis which you can refer to, so I will not belabor this point except to say that even now, in the year of our web 2023, it is all too common for pages on big-name websites to take multiple seconds to fully load and become functional.
Text is quick to download. Pictures are quick to download. By today's standards, even 1080p video is quick to download. We find ourselves bathed in technology that is too efficient for our feeble minds, so we find new ways to slow it down.
One effective technique is to connect the website to a dozen different advertising and tracking services, each of which will launch a series of network requests to separate domains over separate connections, downloading and parsing more and more javascript, adding more and more click handlers and scroll watchers and background processes and over time shooting out countless telemetrics about how engaged you are. That'll do it.
People don't want to wait a whole minute for a news article to load, that's much too long. Three seconds is slow, but tolerable to most. One second is better, and it's pretty excellent when a page finishes in under a fifth.
But publishers do not strive for excellence. They strive for maximum engagement while maintaining minimally tolerable speed. If they can spend 200 milliseconds sending you meaningful content and 2800 milliseconds sending you ads, they'll do it. All further efficiency gains lead only to more consumption.
I remember when watching videos on the internet meant letting them buffer for thirty seconds since the download was slower than the playback. Now, watching videos on the internet means letting the thirty-second ad play before you can start. Funny how we instinctively hinder ourselves from progress.
As computers have developed over the decades, we've come to expect higher resolution screens, higher fidelity audio and video, and larger storage capacities, but for some reason our tolerance for slow pageloads doesn't seem to crack through this barrier of one to five seconds. There's a level below which people just don't care about an increase in speed, so the publishers are free to use the excess capacity for advertising. You've probably even heard of software that has fake loading bars added because it gives people confidence that the computer is working. Hardware designers keep producing faster computers, and we are all too happy to squander them.
Here's a quaint documentary from the 1960s called Advertising: What it's doing to your life [11]. For this section, I want to pull a particular quote:
If the product isn't all it's advertised, you'll never buy it again. This is important because it forces the advertised product to maintain a reputation. And any time it fails on quality or value, it loses you and your business. Now that isn't true of an un-advertised product, because it has no reputation to maintain. And it isn't true in the case of an advertised product that only seeks to sell you once.
And comment by Hacker News user WalterBright:
I asked the prof who taught my accounting class about his career in used car sales. He said you could tell a good dealer from bad by how long he'd been in business. A good lot will last more than 5 years, because by then he'll be running on repeat business rather than running out of suckers in the community.
What the 1960s documentary didn't anticipate was the advent of the internet, which gives the product an effectively endless supply of new potential customers. So even a product that "only seeks to sell you once" has significantly more opportunity now than it did in the 60s. It's not easy to get a bearing on a company's reputation when they only exist as an Amazon brand page with product reviews of questionable veracity, especially when all they have to do to get a clean slate is take down their Amazon page and put up a new one with the exact same poorly photoshopped pictures.
This tactic of slapping everyone once isn't the most lucrative in terms of absolute dollar figures, but is sufficiently low effort and low cost that some product sellers would rather play this way than just make a legitimately better product. To continue the theme of advertising subverting the principles of capitalism, try to imagine how any of these scam-and-spam pieces of junk would get even two feet off the ground without the ability to advertise to fresh gullible eyes all day long. [12]
If you slapped someone in the face a hundred million times, I think you'd go to jail. But with a bit of care, I think you could get away with slapping a hundred million people once each. Let me know how it goes.
[11] You'll find that the documentary as a whole is apologetic towards advertising, its importance, and how it creates value and jobs. I recommend giving it a watch, but if you were hoping for a progressive anti-advertising message from the 60s, sorry!
[12] I can think of one market segment where crap products can survive long-term without the help of advertising, and that's where the buyer is not the ultimate consumer. Think gift shops full of cheap trinkets, where the buyer doesn't know or care about any of the brands' reputations, and the gift recipient will say "thanks, that's so thoughtful of you" no matter how bad it is. Thus, there is no feedback loop for consumer opinion to affect buyer behavior.
People are taking the piss out of you everyday. They butt into your life, take a cheap shot at you and then disappear. They leer at you from tall buildings and make you feel small. They make flippant comments from buses that imply you're not sexy enough and that all the fun is happening somewhere else. They are on TV making your girlfriend feel inadequate. They have access to the most sophisticated technology the world has ever seen and they bully you with it. They are The Advertisers and they are laughing at you.
You, however, are forbidden to touch them. Trademarks, intellectual property rights and copyright law mean advertisers can say what they like wherever they like with total impunity.
Fuck that. Any advert in a public space that gives you no choice whether you see it or not is yours. It's yours to take, re-arrange and re-use. You can do whatever you like with it. Asking for permission is like asking to keep a rock someone just threw at your head.
You owe the companies nothing. Less than nothing, you especially don't owe them any courtesy. They owe you. They have re-arranged the world to put themselves in front of you. They never asked for your permission, don't even start asking for theirs.
— Banksy
We've talked about the media industry competing to reach more eyeballs, and much of this competition takes place in public. "Visit Farmer John's farm" doesn't cut it. Advertisements must get bigger, brighter, flashier, and more animated all the time in order for advertisers to continue out-competing each other. You may have noticed how many advertisements show people dancing, because watching people dance is naturally hypnotic. Roadside billboards, in all their awful 672 square foot glory, have been electrified so they can show a rotation of animated advertisements instead of a single static photo, and they can be bright enough to signal incoming spacecraft.
It is hardly possible to step outside without being advertised to, unless you recede all the way out into the woods. As I prepared to write this paragraph, I had to ask myself, what would the alternative even be? What kind of cityscape am I imagining that would allow me to be out in a public space and not be advertised to? It is such a foreign notion that it is difficult to even answer. Buildings in a public space are either homes or businesses, and the businesses will want advertise on their space, right?
Well, if you're interested in foreign notions, look to São Paulo, Brazil, which enacted a "clean city" law in 2006.
Admire also the interior of Amsterdam's central station, which decorates itself from floor to ceiling with centuries-old artwork and heritage instead of advertising. Because when a city knows what the hell it's doing with its funds, it can spare some for art and atmosphere instead of pimping out the very walls to advertisers. Who knew!
I think it's not wrong for a business to have their name on a sign, but our cities are just totally soaked in advertising that isn't necessary. Billboards, windows, telephones, train stations, bus stops, hell, even the buses themselves are wrapped in advertising reminding you who you should thank for sponsoring the continued existence of the public sphere, as if it would otherwise collapse. Sixteen years later, São Paulo hasn't collapsed.
In 2019 a company called StartRocket wanted to launch logos into space [13].
"We are ruled by brands and events," he told Futurism. "The Super Bowl, Coca Cola, Brexit, the Olympics, Mercedes, FIFA, Supreme and the Mexican wall. The economy is the blood system of society. Entertainment and advertising are at its heart. We will live in space, and humankind will start delivering its culture to space. The more professional and experienced pioneers will make it better for everyone."
The company didn't share how much a space advertisement might cost, but a pitch deck sent to Futurism opined that brands will pay for the ads because the "ego is brighter than the sun."
"If you ask about advertising and entertainment in general — haters gonna hate," Skorupsky said. "We are developing a new medium. At the advent of television no one loved ads at all."
If you're in the mood to deface some advertisements, here's a design you could print out on sticker paper and fill in with marker:
[13] The next step in cola's domination of the universe.
It is no secret that people who receive things from sponsors feel pressured to keep the sponsor happy by censoring themselves. For example, a product reviewer who receives free samples from manufacturers might choose to temper their criticisms so they don't risk the chance of not receiving the next free product. I can respect reviewers like Mr. Mobile who end every review by explicitly denying any editorial input from the manufacturer, but I also think that his criticisms are usually quite lightweight. Even if he's not being told what to say, I can tell that he's either self-censoring or just not as discerning as I would be in his position. Better yet are the likes of Project Farm who always purchases everything he tests — when he says "very impressive!" it actually means something.
Self-censorship also includes not talking about particular topics deemed taboo by the sponsor. The Youtube Adpocalypse and Youtube's COPPA agreement are both great example of a mass chilling effect that left video creators unsure of what they can and can not say or show. Superstition like "you can say the f-word, but only after 30 seconds" became officially encouraged for a while. People became worried that everything they do has to be family-friendly or else they'll get banned. Youtube's continued decline into artificial incompetence and automated decisionmaking have only made things worse. Even now, many are superstitious that saying the words "covid" or "Ukraine conflict" out loud will weight the video towards being demonetized.
I already feel that basing your income and internet presence on a free website is risky at best, but in a basic sense I don't mind platforms having rules and people abiding by them. As time goes on, though, we've seen more and more people consolidate themselves under a shrinking number of platform brands, so the rules that apply to creators of today are ever more monochromatic. If you pay the creators that you want to see succeed, and they diversify or even self-host their publications, and we all come to our senses and start using RSS again, we'd see a lot more color.
The internet presents us with enormous opportunity to develop the long tail, and we are refusing to take advantage of it. In the ages before the internet, if your interests were too niche and specific, you'd never be able to get in front of enough people to find the like-minded among them. Now, with the internet, we have the possibility for people around the entire world to reach each other in milliseconds, to catalog and index and search through all that exists, but instead we stick to what we know, and that's the television-era way of doing things.
There is a very well-known mantra that goes "if you're not paying, you're the product". You can use Facebook for free, but only because Facebook is selling you to advertisers. If you've heard this once, you've heard it a thousand times.
What this means is that your eyeballs and your attention are the product being sold by the publisher to the sponsor. The sponsor doesn't care about you as a human being, they care about how many clicks are landing on their website, and the publisher promises they can generate so many clicks in exchange for CPI. We like to think of ourselves as the customer using the Facebook product, but in fact we're more like cattle on the Facebook ranch, and the advertiser is the customer hungry for steak.
Cattle ranches like Facebook, Instagram, and Twitter do odd things that make the service less convenient for the cattle, like obscuring chronological timelines in favor of discovery and recommendation systems. One might say that these changes make the product worse, but since the real product is the cattle's mere continued existence and not their happiness, these changes actually make the product better from the perspective of the advertiser.
This also explains why it's so difficult for users to get help when something is wrong with their account, and why their opinions are rarely considered when changes are being made to the system. The happiness of the cattle is not really important, and it's better to pursue two new ones than help one old one. At this point I am basically repeating what I said earlier about becoming a media production house.
That's fairly straightforward, but there are some situations where the "you're the product" concept starts to get a little twisted. That's when a content platform shares some of its advertising income with the content creators. Youtube, for example: They're deleting my channel, but they don't know why?
If Google/Youtube were NOT a monopoly, they would have invested significant amount of money in customer support. However, there is zero. They are saving hundreds of millions in support costs by not delivering any support. Unlike more overt monopolistic actions like raising prices, etc, what they do instead is increase their profits by taking away functionality that their customers should be receiving.
https://news.ycombinator.com/item?id=24575131
They do have support infrastructure for their customers. Youtube content creators are not customers, they're more akin to contractors (when paid) and volunteers (when not). In fact, google is the customer in this relationship, and they are within their rights to stop buying the product without having to explain why.
It is on content creators to diversify their business. If a contractor has only a single customer because that customer is the most profitable, would you pity them when they are fired by that customer? Or would you call them bad at business for failing to diversify?
We have a situation where simultaneously:
But the thing that makes this relationship even more twisted is that even though video creators expect to get paid for their videos, they don't actually have any contract guaranteeing it. Youtube has a system where videos may become "demonitized", meaning they are not eligible to receive advertisement money, if Google determines that the video is not suitable for their sponsors. Officially, each video is offered up to Google for free, and Google may or may not decide to kick some revenue towards the creator. Don't get me wrong, this lack of contract and casual business relationship works in favor of the creator too: they have no production quotas or deadlines, and they can publish as much or as little as they want. Lots of people try making videos for a while and then get bored of it, so we can't expect much in the way of contractual work. But the difficulty of getting paid by Youtube has led many video creators to make deals directly with advertisers and perform the advertisement as part of the video. This leads to viewers seeing twice as many ads in the practical sense, except in the minority case where Google decides not to run their sponsors' ads on the video because the topic is too risqué for them.
Collectively, creators have complete leverage over the site's ability to operate. Without new videos, Youtube would be in big trouble with the advertisers. But individually they are basically holding out their hats and hoping they'll catch some of the falling coins. The strongest threat that an individual creator can make is "I'm not gonna upload any more videos for you!", which measures at about 0.0001 on the Richter scale. Google is always prepared for individual creators to come and go, which is why they don't draft contracts or guarantee payment, so without significant collective action on the part of creators hurting the bottom line, Google has no incentive to change. Not to mention you'd be asking creators to sacrifice their own income by withdrawing their hat.
I will take this opportunity to say that I agree with the perspective that full-time youtubers are like contractors relying on a single client with no contract, and if they don't diversify their income it's their own fault. It's bad business sense with little room to cry victim. This is similar to what I wrote in Cancel This Album!. The situation with Youtube advertisements is not new. Every single person getting into Youtube with the goal of making money has had ample time to assess the system and decide if they're willing to try their hand with it anyway. Besides, the kind of people who get into Youtube with the goal of making money are not the kind of people I care about, and I am more than happy for them to bail when it doesn't work out. The ones I care about are getting my patronage separately.
One more good comment:
People could stop using Google today but most don't, because Google is just so much better than everyone else at searching.
Should Google/YouTube be regulated because people dislike what the company is doing, but just not enough to actually stop using their products?
"Hey", said the director of marketing to the product manager, "the users on the free plan are earning us $3.50 per month in advertisements, and the users who upgraded to the premium plan are earning us $8.00 per month."
The product manager eyeballed the quarterly report and saw that these figures were accurate. "Things are looking good."
"But if we show them the ads too, we could be making $11.50."
Hulu is one of the more notorious examples that comes to mind. You can find lots of people wondering why they still see ads after upgrading to the plan called "Hulu (No Ads)". Hulu's help center has an answer to this question: their service provides both on-demand media and live television, but "No Ads" only refers to the on-demand media because the live television is, well, live from another broadcaster that controls the stream. That answer is pretty reasonable in my opinion but, gee, maybe they shouldn't call it "No Ads", huh? A reasonable consumer might be misled into thinking they're paying for a plan that will not include any advertising. Perhaps Hulu is only targeting the unreasonable consumers.
"That's fine", you say. "I don't use Hulu, I use Netflix. I pay for Netflix and it has no ads". Well, except.
The current state of so-called smart televisions is a horrifying glimpse into this future of being advertised to after you've already paid. There are endless reports of Samsung televisions showing ads in the UI. And when you see the option to "turn off personalized ads", that doesn't mean you get to turn off the ads, just that they won't be personalized any more. Probably. I'm waiting patiently for some evidence of manufacturers delaying the showing of ads until a 90-day return period has expired.
The tech-savvy TV buyers know that you should never, ever give your TV your wifi password, because it will use it to advertise to you. But get your tin foil [14] ready because soon that won't be good enough — cellular providers offer IoT data plans for around $1.00 per month, or less when arranged in bulk. Your next TV could very well come with a cellular modem and a SIM card inside, essentially all the important guts of a cell phone, so that it can connect to the internet all by itself. The TV manufacturer would pay the monthly cost of the SIM and you'd never know it's there.
"But the advertisements subsidize the TV and make it cheaper for the consumer", you'll hear. Firstly, I think this is basically hogwash. If it's true at all, it will only be a temporary effect. The manufacturers picking up money on advertising can afford to drop the sticker price and take a loss on the TV itself to undercut the competitors. But once all the competitors follow suit and every television at your local big box store has advertising built in, we'll be back to square one in a new fresh layer of hell. Secondly, the whole Moore's law thing took place from the 1960s to the 2000s and demonstrated within one lifetime that electronics technology can become better and cheaper without every single transistor sending you spam mail. To say that letting your TV advertise to you has opened up new doors for affordable technology is myopic. This isn't the only way forward.
The TV is one thing. It's a media device anyway. Next up is your refrigerator, dishwasher, clothes washer, dryer, air conditioner, heater, stove, oven. Looks like you're running low on detergent, why not pick up some Tide™? Looks like you've been running the AC pretty often, you should ask Home Depot™ about installing some double-paned windows to improve your home's insulation. You've started cooking more recently — new hobby? — you might like a fresh set of Lodge™ cast iron skillets. The manufacturers will not put a screen on your appliance that tells you these things, but they'll collect the data and use it to decide what you see on the web tomorrow [15].
"As long as a pregnant woman thinks she hasn't been spied on, she'll use the coupons."
And every time you see a "smart" version of a product that you didn't know needed to be smart, you should be very suspicious. As soon as the manufacturer of your bed, your couch, your pillow, your dresser, your cabinets can convince you to plug your furniture into the wall, you're taking the bait and they're going to use your own electricity to advertise to you. It's a bad habit to get into.
There's another point that I was only recently enlightened to. One way that appliance manufacturers are able to get these anti-user products into users' homes is by making deals with home builders and landlords, and having their appliances installed before the would-be home buyer has any say in the matter. After all, the home builders aren't the ones that have to actually use it. This is another example of advertising subverting the foundations of capitalism: the manufacturer doesn't need to win over the customer with a good product, they just need to find novel ways of getting in your face.
This is okay though, because as we all know, the free market will sort itself out. You as a home buyer will simply have to do comprehensive research on every single electronic device that is included in the home and be ready to drop the entire deal at a moment's notice. In this economy. Good luck!
[14] Reynolds Wrap™ is perfect for making faraday cages and also hats!
[15] But remember, the only reason your stove can influence the ads you see on Twitter is because Twitter is selling you out, and you've got to blame both parties.
Spam is built upon the abuse of systems by definition. Unlike sponsors, who make a deal with the publisher to show ads in their space in exchange for payment, spammers are people who try to slip between the cracks of the system and get their advertisements directly to you. Like bomb-carrying terrorists, spammers will target spaces that:
Your email inbox and your telephone are spaces for communicating with people you know, and spammers abuse it to send you junk. Web forums are spaces for conversation, and spammers abuse them by making fake posts. Grocery stores are spaces for buying food, and spammers abuse the traffic flow to hand out fliers. Parking lots are part of our transit system, and spammers leave advertisements under your wipers because you're not there to stop them. The front door of your house is for yourself and your guests, and spammers abuse it by turning it into ad space.
The problem with spam is not just that it's annoying, but that it converts your entire life into an arms race. Spam is hostile. It is mean. Spam takes every aspect of your life and turns it into an opportunity to make a buck off of you. No matter how hard you work to avoid advertisements and carefully pick the publishers you want to pay for, spammers can override your decisions and advertise to you anyway. I am not kidding when I compare spam to terrorism, though I am exaggerating. Spam positions you against enemies you didn't know you had. Enemies who come from afar to your place of residence to disrespect your time, attention, and belongings, and sneak away. Unlike a TV which can be turned off or a magazine which can be closed, spam offers no means to opt-out. Spammers will hit you and run without showing their face. What are you going to do about it, not have an email address? Not have a phone number?
People dump their ugly fliers on your doorstep, and for some reason the onus is on you to clean it up and hang a No Soliciting sign to stop it from happening again. Do we also need to hang a "Please don't throw eggs at my house" sign, just in case? How about "No Bombing"?
Consider for a moment the extraordinary amount of resources that have been utterly wasted by spam. How many millions of square miles of paper are printed into pre-approved credit card offers so they can go straight to the shredder. How many talented software engineers have been relegated to writing spam filters, email blockers, abuse heuristics, shadowbanners, phishing protection, and anti-spoof measures just to stop worthless dirtbag spammers from polluting their website and the internet at large. All this effort could have been put to better use.
Spam is a crime against humanity and I'd like to see the worst offenders jailed.
Even if we consider the above the be a list of reasons why ads are evil, some may say they are a necessary evil. Below are some reasons that advertisements are less necessary than we think.
When people complain about ads on the internet, mobile apps, and so forth, there is a common defense that always comes up. It's that "website owners/app developers need to eat too!". I agree with this and will take it a step further: everyone needs to eat. No, further: everyone deserves to eat. And everyone deserves to have a comfortable home and enough time in the day for leisure. Woah! So progressive! I'm pretty ahead of the game here. But how can I reconcile such a utopian vision with a rejection of the ads that make all of these things possible? You know that nobody ate until the advertisement was invented.
Whenever I think about this, there's an analogy that always pops into my head. I've had it for years, and it goes like this:
Suppose someone decides they want to make a living selling bottlecaps, or refurbishing used napkins, or decorating toilets, or teaching underwater basket weaving [16]. So they stand on a street corner peddling their wares and find they don't get many takers. Turns out people don't want to spend money on that. Panic sets in. "I've set my sights on this job!" they cry. Rent and bills continue to pile up but the money's just not coming in.
The situation becomes desperate as they realize their monetization scheme — you know, exchanging their goods and services with customers for money — isn't going to pan out. With the business failing and the market clearly not ready for their idea, they finally make the obvious choice... huh?... find another job? No, I mean they start yelling at passersby with a script someone else is paying them to say, and slipping tracking devices into their pockets as they go. And if any of them complain, it's the same old story: I'm sorry you don't like the ads, but used napkin refurbishers need to eat, too!
Such is the current state of the software, web publishing, and mobile app industries.
I know that our society has got a pretty serious problem with undervaluing software. Why is it that I'm willing to spend $10 on a pizza that I'll get three meals out of, but I'm not willing to spend $10 on software I'll use hundreds of times over the course of years? I don't know. Partly because we have problems assigning value to intangibles, and partly because I've been conditioned by the plethora of great, free, no-ads software I've already got. And partly because of DRM which aims to strip control even from paying customers, but that's another matter. If I was getting free pizza regularly I'd surely stop paying for that, too, even if the paid ones were a little better.
But that's not really the point. That's an is/ought problem. Consumers ought to be willing to pay for good software or web experiences or mobile apps, but the reality is they mostly aren't. The economy and the world in general is full of is/oughts, and when it comes to making a living and paying rent, I think most of us understand that we have to follow the is. What absolutely boggles my mind is that developers whose goal is to make money with their idea [17] can recognize the state of the industry, understand that the likelihood of making sales with it is near zero, and then proceed anyway before, oops!, needing ads to pay the bills. In fact, I'm being disingenuous here by implying that developers even intend to use honest sales in the first place; the situation today is that ads are the expected and planned business model for many or most. Look at how many websites and apps are launched with analytics, tracking, and ads baked in from day one.
Can you imagine applying this line of reasoning to any other industry? Mom, when I grow up I'm going to become a napkin refurbisher. But darling, no one's going to pay for that, are you sure you can make a living? It's okay I'll run ads. Mom, I'm going to start a business decorating toilets. Will anyone pay for that? Maybe a few, and I'll run ads to earn the rest. Mom, I'm going to enter a market in which there are not enough paying customers to make a living, but it's ok I'll run ads. Does this not sound totally wild?
My feelings here would be different if we were still in the exploratory phase of computers, back when we weren't really sure if goods-for-money style transactions could work here. But we're not in that phase. Those pioneers have come and gone, and they left a bunch of signposts saying "people don't pay for this stuff". Very occasionally, someone will realize a market opportunity that does work. Steam sells loads of games and does so because "it's easier than piracy". I don't use Spotify but I've heard they're in a similar position. Netflix captured the movie-streaming market first, and were worth paying for until the more recent fragmentation of everyone trying to start their own streaming service and pulling their licenses from Netflix. I just simply cannot sympathize with someone who knows that making websites or mobile games doesn't pay the bills without ads, then starts doing it anyway and complains that they can't pay the bills without ads, despite not having a remotely unique take on the problem. Likewise, I expect that you would not sympathize with me if I tried to start a napkin refurbishing business and found it to be unsustainable.
Job titles are descriptive, not prescriptive. It's not like you are born an app developer and therefore you must make a living making apps. You're an app developer because that's what you chose to do. So when people say "app developers need to eat too!", all I can think of is "then why did they choose that job!?". This is not discrimination against something out of your control. Everybody needs to eat, so the fact that they become full-time app developers confounds me.
I don't understand why we're so hell-bent on making apps and websites and social media networks. Our culture has become absolutely tunnel-visioned, barrelling along on the locomotive of PUBLISH MORE PUBLISH MORE, we've become incapable of considering that our hobbies weren't meant to be full-time jobs. All we can do is double down, insist with our dying breath that Twitter must go on!, injecting it with engagement-boosters whenever growth slows. Have ye no shame, corrupting your work like this? Didn't you begin the project out of passion?
I don't know why we've developed this "all business ventures must grow forever" mindset, especially when it leads to the corruption and rotting of the original business. If you're running a free web service and it's costing you too much to host, I'd have way more respect for you if you just said "hey everyone, I can't afford to keep doing this out of pocket, we'll have to cut back on the scope of our project unless the community would like to contribute some funds". It doesn't seem like that level of honesty should be so hard to come by, especially when speaking to the very people that are making your service successful, but most of the time it's straight to the advertisers for help instead.
If this line of reasoning works for web/app developers, why haven't we seen the degenerative collapse of other industries in which people do unprofitable things but spin it off into an ad-slinging business to make ends meet? Why isn't every single auto mechanic, grocery store, and restaurant offering their primary service for free, and making up for it by showing advertisements for sponsors [18]? Well, first and foremost it's because there are actually customers willing to pay for those. But moreover, the technology industry is unique because it's the biggest force-multiplier the world has ever seen. Real-life businesses are going to be bound by the high costs of property and lights and inventory and staff. If Grocery Mart gives out groceries for free and hopes to make their money on third-party ads, they're gonna have to show a hell of a lot of ads and still will never achieve a big enough reach to make it pay off. Meanwhile, ads on the internet are highly passive from the point of view of the website owner or app developer, and they reach thousands of times more eyeballs, and the cost of hosting a website or distributing an app's worth of megabytes is dirt cheap compared to leasing store property and giving away real inventory.
It's all a bunch of is/ought/is/ought/is/oughts. I'm gonna go crazy over this stuff [19].
[16] When I equate the writing of software with these trades, I'm not doing so on the basis of the craft itself. I'm doing so on the basis of the number of paying clientele, and furthermore I'm exaggerating to make a point. Writing software is much more useful and impactful than refurbishing napkins, etc etc etc, and we could harvest a million is/oughts out of this situation.
[17] If your goal is not to make money, then proceeding with an unprofitable idea is perfectly fine. That's called having a hobby. I'm talking about people who want to enter a market that won't support them and then saying Sorry! I had to run ads or I'd be out of business! as if that outcome wasn't obvious from the beginning, and as if staying in business was mandatory.
[18] Yes, grocery stores do have signage and priority shelving spots which suppliers pay extra for, and fast food chains have agreements with ketchup and soda suppliers. The difference is that shelving is physical, limited real estate. So the decision of what to put where comes down to logistics with sponsorship as a tie-breaker. Furthermore these things are contextually relevant to the domain, and I enter these places with the expectation of spending money, neither of which are the case for web ads.
[19] I already have.
During the previous section, you may have been thinking that a developer slinging ads on a free site or app is more acceptable than a napkin refurbisher slinging ads, because websites and apps improve our lives in a way that refurbished napkins don't. This is also true for Youtubers who quit their day jobs to make videos, funded by ads.
One facet I want to express is that the value, I mean benefit-to-the-world value, of ad-supported websites and services is almost universally overstated, and the value that is there can hardly overcome the damaging cost of ads. After all, how valuable could it really be if nobody's willing to pay for it except the sponsors expecting a return on investment? Humanity survived for many thousands of years without Instagram and we can continue to do so. It's just not very important.
But surely if I got my wish and ad-supported websites all shut down, there'd be nothing left, right?
There would be less, that much is true. There'd be a lot less. But increasingly, and overwhelmingly as of late, that's sounding like a good thing to me. I don't want more, I want better. Like, if you've got one gold nugget and a whole bunch of trash, and you throw away the trash, yeah that's the majority of your content. But it was trash content, and to be rid of it is good. Focus on the gold. What's that, Facebook wouldn't be able to continue operating if it weren't for ads? The History Channel, a shell of its former self and a disgrace to its name, would have to stop broadcasting? Okay, I'll take it!
The internet used to be small, but most things you could find were interesting or at least made by someone who was genuinely interested in making it. Now the internet is enormous and nobody cares about anything except getting clicks. Browsing the internet now is like swimming in a polluted lake. It's miserable and discouraging.
Veritasium [20] gave a presentation about fake news and facts on the internet:
I was an optimist. Maybe I was naive about the internet. My thinking about having an international communication system whereby anyone anywhere can share anything — regardless of their education background or their class standing — and get access to real information through Wikipedia. My thinking was the internet was going to make everyone happier and more informed, more educated, and probably more tolerant of others around them.
His thesis is about misinformation and intolerance [21], not advertising, but I share his feelings of disappointed optimism. What was once called the information superhighway and touted as all of human knowledge at your fingertips is now sadistically impossible to navigate, with little tidbits of value hidden beneath mountains of SEO gamification, low-density listicles, promoted posts, and flat-out spam.
When I say that I long for the internet to be small again, I'm not saying I want the clock to roll back in time — that would mean there'd be fewer people connected and I certainly want the internet to be global. But I want it to be personal, and passionate. I want to find things that people made because they enjoyed making them, not because it was the most algorithmically optimal thing to make. I'm sick of communications platforms becoming walled silos because if they allow anyone else to access their data they'd lose their advantage over the analytics that feed their advertising. I'm sick of gmail being synonymous with email. I'm sick of everyone and everything being factored in to a monetization strategy writeup.
For some people, it is a shock that anybody would do anything without the motivator of profit, but this is actually normal. Musicians make music because they like doing it. Artists make art, photographers take photos, programmers make programs, cartographers make maps, linguists make languages, carpenters make furniture, chefs cook, animators animate, sculptors sculpt, and writers write... for fun, it turns out. If you look around in places that aren't ravaged by poverty, where people don't have to scrape by to survive, where people have leisure time to do the things they enjoy, you'll find that it's in human nature to share freely.
The insider scoop around here is that I pay $12 per year for my domain name and $4 per month for web hosting. For email I pay about $0.40 per month [22]. For storing large quantities of files I pay $0.015 per gigabyte per month as seen here. I run this website for cheap and I pass the savings on to you. If you scoff at this feeble blog and dream of something more impactful, you should know that Hacker News, one of the best forums I know of today, still runs on a single (good) box, as it has for 15 years. Computers are pretty good at what they do, and excellent things can be made and shared on the internet without the help of advertisers. If only you choose to make it happen.
I now reuse this quote, that I might not bungle it:
Writing for money and reservation of copyright are, at bottom, the ruin of literature. No one writes anything that is worth writing, unless he writes entirely for the sake of his subject. What an inestimable boon it would be, if in every branch of literature there were only a few books, but those excellent! This can never happen, as long as money is to be made by writing. It seems as though the money lay under a curse; for every author degenerates as soon as he begins to put pen to paper in any way for the sake of gain. The best works of the greatest men all come from the time when they had to write for nothing or for very little.
I use adblock and I visit websites which are fueled by ads. I don't whitelist anybody. So I don't have a right to complain or fuss when they eventually shut down, since I was never helping them stay up. That's fine. That's why I download everything that I care about. Ad-supported services live on a treadmill, but I don't.
Suppose I get my wish and ads disappear forever, and every website becomes either purely-free, or subscription-based, or shuts down entirely. Which ones would I pay for? Out of all the ad-supported websites and services that I use today, the only one with content that I consider worth paying for would be Youtube, because video is my favorite medium and I'm well aware that hosting video costs money [23]. If reddit were to die I'd be 50/50 bummed and relieved. Pushshift has got it backed up anyway, so as far as historical knowledgebase goes we wouldn't be losing much. Hacker News is already free without ads, though subsidized by YC's business ventures.
[20] I like Veritasium's videos but his descent into clickbait is a top 10 saddest anime moment for sure :(
[21] I won't say that advertising and intolerance are directly causally linked, but I will say that stormfront.org has Google Analytics.
[22] Can you believe that it only costs forty cents to get off of gmail? What are you waiting for??
[23] If I were to pay for Youtube, I'd want the money to be used only for hosting the videos, not for paying the creators. Youtube has gone through periods of prioritizing video length, or watch duration as a percentage, or publication frequency, etc. for controlling the algorithm and payout. Goodhart tells us that distributing the money based on any of these factors will make the creators change their behavior and poison the system. If I want to give the creators any money, I'd use Patreon to pay them directly, and I have done so. The cesspool channels that no one is willing to directly fund, unable to survive without advertisements, would go extinct. We'd also lose some genuinely good creators who can't devote their time to making free videos, and that's a bummer, but it's a sacrifice I'm willing to make in exchange for the higher median quality level.
I would like to quote a portion of this champion comment by Hacker News user eevilspock which permanently altered my perspective of advertising. It starts with the "if you're not paying, you're the product" mantra we all know and love, but then takes it a step further which I hadn't seen before:
IT'S NOT FREE
We're not Facebook's customers, advertisers are. But we are the advertiser's customers, and the cost of the "free lunch" is simply shifted to the price of the things we buy from them. In other words we still end up paying for the full cost of Facebook. Costs may even shift regressively, to advertised products predominately consumed by those with lower incomes, in which case the poor are subsidizing the better off.
IT'S MORE EXPENSIVE
Not only are you still paying for the full cost of the Facebook product you use, you are paying for all the advertising overhead: the costs of its advertising technology and infrastructure (huge, btw), the agency and creative costs [...], and the advertiser's big marketing departments (that often outnumber and outspend the people making the product!).
[...]
Our identities and privacy are bought and sold to the highest bidders. And where do the bidders get their money? From us of course! A double whammy!
This comment left a big impact on me and I can't possibly discuss advertising without mentioning it. Whenever I imagine myself getting into a conversation about ads (which is often), I imagine myself paraphrasing this argument.
Investopedia says that Coca Cola spends $4 billion per year on advertising, out of their $35 billion revenue. Where did Coke get 4 billion dollars to spend on ads? From the customers' pockets, of course. That's a percentage of the cost of every single drink that winds up going to their marketing department so they can make advertisements that you don't want to see. The idea that "ads allow publishers to make things available for free" is cumulatively false because any time you buy a Coke, your money is going to all of the publishers they sponsor (even the ones you don't read) and all of the operational and staffing overhead involved in the advertising machine.
Earlier in the article, I said "by displaying a sponsor's advertisement alongside your product, you can earn more money without having to make your product better". In that section I wanted to focus on the publisher's perspective, but there's an interesting dynamic here that we can evaluate from the sponsor's perspective. After all, both parties are hoping to increase their revenue, but they approach it in opposite ways: the publisher reduces the price of their product, possibly down to free, and "makes it up in volume" with the help of the sponsor; meanwhile the sponsor is dishing out money to the publisher, so they need to recoup that cost somehow. Isn't that a bit strange? What techniques are they using to earn that money back, and why couldn't the publisher apply those techniques to their own product in the first place, so they could earn their way without showing ads? Why are so many publishers unable to get enough money from customers' pockets to stay afloat, while Coke is pulling in enough money to support both themselves and the publishers?
It is a brain-wrinkler for sure. I have not figured it out. Perhaps it is like the phrase "those who can, do; those who can't, teach". The alpha males who know how to sell a product become the sponsors, the beta males who can't sell their product take on sponsors. Of course, the sponsors are the ones coming up with disgusting, manipulative psychological tactics to do their selling, so it is not exactly an honorable title. Many of them wouldn't be able to survive without stooping to new lows every week [24], but I guess being abusive, uncaring, and ready to kill is what makes one an alpha.
Part of the problem, which I touched on earlier, is that people have been conditioned to not pay for software or websites, whereas we're already accustomed to paying for sodas. But I don't think that's the full answer, because the internet is young compared to the usual suspects of sponsorship advertisements: tv, radio, newspapers, magazines. Television and radio were uniquely dependent on sponsorship revenue because it's not really possible to charge someone for access to a radio frequency unless you encrypt the datastream and sell them the key, which wasn't developed at the time. But print media was, and still is, something that the reader paid for, yet it became swamped with ads quite a long time ago. Were they just too beta to compete the normal way? I don't know yet.
Here is another take by bondarchuk,
"What about the revenue the city gets from advertising space?"
Someone pays the city to show me something. That means the ability to show it to me is worth more to them than what they pay the city. It also means that at the end of the day, the money is somehow coming from me, and this amount could be larger than what the city gets out of it, even. Therefore I would actually save money if the city abolished advertising and just raised taxes a little.
If ads were eliminated from the world, everything could hypothetically be several percent cheaper and:
You could instead give your money to the publisher directly, which would definitely be more than they get from the CPI of advertising to you, but you only have to pay them if you think their publications are worth buying.
The sponsor would have to focus on building a strong reputation and making a good product, instead of designing ads that manipulate people into thinking they have a good product.
The sponsors who cannot maintain a customerbase without the help of advertisements would go extinct.
The publishers whose products are not good enough to pay for on their own would go extinct.
New businesses would have a hard time getting their first customers, I admit.
Could this really happen? If the marketing departments vanished overnight, would product sellers actually reduce the cost of their product to match their reduced expenditure? No. Customers have already demonstrated that they are willing to buy it at the current price. But São Paulo has shown that legislators can force the ads to come down. Once the brand is physically unable to buy ad space, they're going to have to redirect their marketing budget somewhere. Sure, they might just hoard the extra cash. But I do think that if a new generation of customers were to be raised in an ad-free world, and a new generation of brands were to be formed with no marketing expenditure, they would see the opportunity to undercut the incumbent brands who forgot to lower their prices, and a shift may occur.
Regarding point 5, it may be reasonable to legislate a maximum advertising expenditure, instead of forcing it all the way down to zero. Suppose we allow businesses to have advertising budgets, but we clamp it down so low as to stay in the "Visit Farmer John's farm for some tasty corn" territory. That is to say, businesses would not be able to spread themselves thin trying to advertise to the whole nation or world, so they'd naturally have to stay more local, putting young businesses on more equal footing with larger brands and re-igniting a real sense of competition over the quality of the product instead of the psychoterroristic manipulation of the advertisement. I'm still glad to have a global internet, of course, but it would be word of mouth that spreads your product far and wide, not your advertisement.
Making this change is like planting a tree: the best time to do it was 20 years ago, the second best time was 19 years ago, the... um... it's better today than never.
I'm sure you will want to remind me of economies of scale, and that advertisements help companies reach large scales which bring their unit costs down, thus the price of the product can't necessarily be reduced by exactly the amount of the marketing budget if the marketing department were dissolved. I get it.
[24] When I see or hear children performing advertisements on tv or radio, it makes my skin crawl. I wasn't sure where else in the article to mention this, so I'm putting it here. It's low.
Although I am vehemently against ads, it's time for me to distance myself from one of the common anti-advertisement arguments. I am not a zealot and I will not blindly agree with any anti-advertising stance that comes my way.
Scenario: A website publishes articles and has ads on the page. A user enables adblock and reads the article with no ads. Is this user in the moral right or wrong?
There are some proponents of adblock who will assert that they are in the right because it's their computer and they should have the power to decide what their computer does. In the very same way that I as a human reader can choose to not read paragraphs that begin with the word "But", I should be allowed to have my browser block anything that calls itself <div class="ad">
, and I should be allowed to prevent any ads.js
from being executed.
I think this is absolutely true. It's my computer, it's my electricity, it's my processor cycles, and it's my eyeballs. Nobody should have the right to run unscrupulous code on my computer just because I visited them once. I am under no obligation to see that div if I don't want to. On that front, this argument is sound.
But, this argument is only good for approximately a single visit before it runs out of steam. When I go to a website for the first time, I don't know how many ads.js
they're going to try to hit me with, and I have every right to armor up before clicking the link. For every visit after that, though, the justification is all but lost. You've seen what they're sending you and you don't like it. Why do you keep coming back? You're not obligated to see that div, but you're not obligated to visit that website, either. You're freeloading. It is immensely obvious to me as a reader that the publisher is only allowing me to visit this page because they assume I will see the ads along with it. It is obvious to me that if they could physically prevent me from reading the page without ads, they would do so.
This is not the same as a reader skipping over paragraphs that start with "But" because those paragraphs are probably not uniquely responsible for the author's income when compared with the other paragraphs. The divs marked class="ad"
are uniquely responsible for their income when compared with the other divs. Where do you think the arms race of adblock-block-block-blockers comes from? It is obvious to me that they did not intend for me to read the page for free, and in doing so I am violating the trust they had in my readership.
Notice that word, "trust". Anybody who perpetuates this "it's my computer" argument is being willfully disingenuous and approaching what is obviously a social problem, trust, with a purely technical solution, adblockers. "Your computer sent my computer a bunch of different bytes, and I had my computer filter out some particular bytes before showing it to me, because I prefer reading it that way. It's not my fault that those particular bytes are the ones that make you money. They're just ones and zeroes why do you care so much~".
Using a technological bypass around the social matter of trust does not put you in the moral right, even if you think a page containing ads deserves to be violated. You're not "getting back" at them for wronging you. You could achieve that by leaving, never to return. Even though I've always got my adblocker on, there is a growing list of sites that I simply do not click on, because I resent what they try to send me.
I think there are some cyborgs out there who do not make the link to the social element of this problem, and only see it as a tech issue. These cyborgs are the ones who go around offering technical solutions to the publisher, like suggesting that they should either suck it up or put in a paywall if they want to keep out freeloaders so much. But that's like telling someone they should have locked their doors better after you've wandered around inside their house, and that they should have known someone would sneak in. It is logically accurate but not morally right.
I started by calling this an unspoken agreement, but when you start seeing "please disable adblock to view this page", then it's very much spoken, I think you'll agree.
Do I still use adblock on ad-fueled sites anyway? Yes! Do I treat the "please disable adblock" popups with scorn? Yes!! But you won't see me using this "it's my computer" argument to defend that practice. I'm freeloading because I like freeloading and am willing to recognize it as such. And if being called a freeloader when you use adblock offends you, then I guess you'll have to stop doing it or grow thicker skin.
There is a subreddit called /r/HailCorporate, whose stated purpose is to point out posts on reddit that act as advertisements. This means giving a brand excessive or undue attention, framing photos the way an ad or product placement shot might frame them, and mentioning brand names when they aren't actually relevant to the event at hand. For example, "My box of Toasty Bites fits perfectly between two of the shelves in my pantry!" could have just said "My box of cereal".
The phrase "act as advertisements" is key. Some outsiders visit the subreddit assuming that the purpose of HailCorporate is to identify posts that are actual, paid, what you might call traditional native advertisement posts. Then they see HC users talking about posts which aren't traditional paid ads, and assume HC users are idiots for thinking that those posts are traditional paid ads. You can see how the logic goes, but it's frustrating how many people don't understand the original premise of HC [25]. HC is not about thinking that Toasty Bites literally paid someone to take a photo of their pantry, it's that the photographer had no reason to call the cereal by name but did it anyway. Here are some other values we can learn from HailCorporate:
You should take pride in what you do, not what you buy. There are a lot of posts on reddit that are just pictures of products that the user purchased, still in their boxes, without any subsequent pictures of the products being put to good use. This is sometimes called box posting. People post pictures of unopened hard drives on /r/datahoarder, new and untouched headphones on /r/headphones, unused pens on /r/pens, translations of Harry Potter in /r/languagelearning, etc. Like, wow, you... spent money? Wouldn't it be more personal, meaningful, and interesting to the hobby community to share what you actually make and do with these things, rather than just the fact that you bought them? Here's an HC post about a povertyfinance post in which the OP shares a screenshot of the store page for a stove they bought. It's not a box post, it's not even a receipt post, it's just the product listing! How eager for internet affirmation must you be to do this, that you can't even wait until it arrives and is installed [26]?
Why do people make these posts? First and foremost it's because buying is easy and doing is hard, and people will make posts that are easy to make. Box posts will make the community regulars groan, but sharing something you've actually made opens the door for people to criticize you and your work and the value of your life. Box posting requires no vulnerability. Everyone in the /r/pens community will like looking at fancy new pens, but they might not like looking at the bad drawings you made with those pens, and that makes box posting the safest option.
I also think a lot of us fall into the mental trap that we're not real artists without the best brand of pens; not real hikers without the best boots and backpacks; not real music enthusiasts without the best headphones. We look at the people doing work we envy, and see that they use expensive equipment, and deduce that the equipment made the work. But this is putting the cart before the horse. Most professionals buy the expensive equipment after they've devoted significant time and energy to the craft.
You've probably heard about people who buy lottery tickets knowing full well they'll never net any money, but they do it because the price of the ticket is worth the small moment they can spend dreaming about winning. This really applies to other purchases too: spend $X00 on something online and enjoy the next 6-8 business days dreaming about all the cool stuff you'll do with it when it arrives... whether or not that actually pans out in the end. Buying is easy and doing is hard.
All publicity is good publicity & Mindshare. Sometimes, a post will come up in HailCorporate where a brand name is juxtaposed with something lewd or offensive. Imagine that someone decides to mock a company by taking a picture of Nazis [27] and replacing the swastikas with the company's logo. Of course it's not a real ad for the company. They didn't pay someone to draw them as Nazis. But it can act as an ad by bringing the brand into the viewer's mind.
Perhaps you've heard of the Streisand Effect, named after Barbra Streisand after she tried to prevent some photos of her house from being published, but in her efforts attracted more attention to them. Nowadays, the people who know the term Streisand Effect surely outnumber the people who knew or cared about the house. The context for the original publicity can be completely forgotten while the publicity itself remains, and people remember Streisand's name.
Publicity with regards to brands works in the same way. Maybe that company did something bad and the author was inspired to depict them as Nazis for their actions. The author's intention may have been to shame or mock the company, but it doesn't matter. For every 1 person that knows the details of the situation, there are 10 or 100 people who chuckle at the funny picture and move on, but don't otherwise care, and won't internalize the bad thing the company did, and represent a +1 exposure event for the brand. This is especially true when the post gets a lot of upvotes that carry it out of the topic group and into the general sphere of everybody else. Even if the author of the Nazi photo decides to continue mocking the brand and "voting with their wallet" by not buying their products, they've created a huge attention multiplier in favor of the brand.
It's like a spinoff of the Miranda warning: "anything you say or do can and will be used to help promote the brand". When all is said and done, the offensive "can't possibly be an ad" content still acts like an ad by making people think of the brand when they otherwise wouldn't have, and the impression can remain after the bad part is forgotten [28].
Is this to say that we shouldn't speak up when a brand does something bad? It's a tricky subject. If the goal is only to hurt the company, I believe the safest course of action is simply to never utter their name again. Brands hate nothing more than not being talked about, and you've got the right to remain silent. Earlier I talked about recognizing our limits, and in this case we should accept that most of us aren't capable of launching a crusade against a brand without accidentally creating more converts for them. If the problem is a specific product they've made, then a review video clearly demonstrating the failure can be effective, but for abstract topics I'd stay clear.
On the other hand, if the goal is to rescue people who have been duped by the company, proceed with caution. It's hard to get publicity out about the company's bad deed without creating disproportionately more exposure events on the fringes. I don't have an answer here, but my advice would be to stick to well-written and well-documented text content rather than images, since images are more easily consumed by the passersby.
Ads have trained us how to take pictures of objects. That is, with the logo facing the camera. If you notice that your box of Toasty Bites fits perfectly on your pantry shelf, take a moment to think before snapping the picture and drafting a title. You've found a funny coincidence involving the size of two things. Does anybody else on the planet care that one of those things happens to be Toasty Bites, or is it sufficient for them to know that it's cereal? Other than scientific reproducibility, what does advertising the brand name contribute to this charming coincidence you've discovered in your kitchen? I for one am at a complete loss as to why people do this, and yet it's amazingly prevalent [29].
I am reminded of Tom Scott's video about the cooperative principle of language, which discusses the balance of explicit and implicit information in our words. Interesting that the shelf never gets proper attribution for its role in the event, right? Where are all the "My box of Toasty Bites fits perfectly in my Home&House pantry" posts? Ah, but the pantry doesn't have a logo on it [30]. We've been trained by advertisements to think that if a product is in frame, it ought to be turned to the camera and the name ought to be read out loud. Advertisers do it that way because they're paid to, but you're not. Feel free to shoot the back side of the cereal box next time.
Once you've gotten past the "awareness" stage of HC, there's not much point visiting the subreddit any more. To do so is a little self-defeating: a bunch of anti-ad people gathered around to look at pictures of brands. In the act of collecting links for this article I've exposed myself to more radiation than I would have received over a normal week. Besides, I personally am no longer interested in reddits-about-reddit. It's the kind of subreddit that you read for a little while and then leave, and that's okay because you'll be leaving with a new perspective on inadvertent advertising.
These days I make a very conscious effort to de-brand my vocabulary. And by conscious I mean that it really does require me to slow down and think about what I say. I no longer use "Google" as a verb, I just say "search the internet" or "search for" or even just "look it up" [31]. Of course I'm aware of brand genericization, so maybe I could help accelerate the effect by using the brand name more often, but, eh, no thanks. It does lead to an interesting dissonance where the genericizations that occurred before I knew them feel normal, but the ones which occur now or in the future feel gross. One of my current borderline examples is photoshop, which I hesitate to reduce to just "photo editing" because I want to distinguish between more sophisticated edits and what the average Joe can get out of Kid Pix.
[25] Well, it doesn't help that HC's current tab-title is "ads, ads, everywhere"...
[26] For clarity, I'm not questioning the discussion of the stove itself. Home appliances are significant, meaningful purchases, and the whole point of the povertyfinance community is to do well with less. No, my criticism here is that OP could have taken a picture of themselves making a delicious home-cooked meal on their new stove, but they just couldn't wait for that and had to talk about the act of buying instead. This is something we should all learn from, and consider what it is we care about enough to share.
[27] inb4 Godwin's law.
[28] One last note: advertisers don't expect ads to make you immediately jump out of your seat to buy something. People like to make fun of car commercials because "Wow, look how happy this family is! I should buy a car!". No, the point is that when the time comes, the first options that come to your mind will be the ones you've seen the most frequently. Unfortunately for the Nazi photo editor, bad exposures contribute to this frequency just as well as the good ones.
[29] Before you think I'm strawmanning, here's one, two, three, four, five, six, seven posts on /r/Perfectfit within a 24 hour period! Big shoutout to this dude who resisted the temptation.
[30] Take a look at the things around your house, and notice what has a conspicuous logo or maker's mark, and what doesn't. I find that when something is ubiquitous, essential, or adds obvious value to our lives, it is less likely to have a logo. The less inherently valuable something is, the more likely it will feel the need to aggressively advertise itself.
[31] Context is important, and I'm not so dogmatic as to let this get in the way of communicating my point. For people who are not tech savvy, "go ahead and google xxxxx" is more easily understood than "go ahead and search for xxxxx" because they might not know what kind of search I'm talking about. Remember to know your audience.
An advertising hall of shame could be infinitely long. This is simply a short list of material I came across or was reminded of while working on this article that I think deserve special disdain.
General internet:
Facebook, Twitter, Instagram, etc. don't want you to see posts in chronological order, because then you'd know exactly when to stop browsing: when you see something from last time! They'd prefer to scramble things up a little to prioritize popular lowest-common-denominator posts, prevent you from ever feeling truly caught up, and hide ads in the mix all the while.
Mobile games have devolved into slot machines with delays, timers, and special events to keep people returning to them frequently throughout the day, achieving enough in each play session to strengthen the addiction but not enough to feel done with the game.
Low quality articles or listicles are often split over several pages so that you can get a fresh load of ads on each page and they can measure how far people are reading (then they can know which corners to cut next time). I'm already sick of pathetic holdovers from physical print in the digital era anyway, but paged online articles are egregiously useless.
Any website that dresses advertisement as user-submitted material:
Google:
AMP pages are pages which Google has downloaded from the publishing website and saved in their own caches, so they can serve the content to the user via Google servers. The stated purpose is to make web browsing faster for the end user (because Google's servers are faster than yours). One way to make your website faster and more AMP-eligible is to use sanctioned ad distributors, say for example, oh how about Google Ads? And because the user is actually visiting Google's servers and not yours, Google gets first pickings on all the metrics they want to harvest from the user. Don't worry, publishers, no one's forcing you to use AMP, but oh don't forget that AMP pages will rank higher in search than non-AMP pages because Google owns the search too :-).
Google brought updates to Chrome and AMP to make AMP URLs appear as if they were being served from the original domain. This continues their mission of keeping people comfortably swaddled in Google-hosted content without giving their poor fragile hearts a scare by showing them the actual google.com/amp URL they're visiting.
Microsoft:
Windows start menu advertisements:
Youtube, the system:
"The algorithm" takes by CGP Grey, Tom Scott, Folding Ideas.
YouTubers have to declare ads. Why doesn't anyone else? by Tom Scott.
I'd like to take this opportunity to advertise tell you about my own program, YCDL, which presents me with a custom interface for subscribing to, watching, and downloading videos. Imagine watching youtube without a "recommendation" feed, autoplay, unrelated spam, or algorithmic determination of what does or doesn't show in the sub box. As long as you can tolerate the slower channel refresh cycle.
I'd also like to advertise spread the word about SponsorBlock, a browser extension which automatically skips in-video sponsorship segments based on crowdsourced reports. The database can be freely downloaded so you could hypothetically implement a system for sponsorblocking locally saved videos. This would be great, since I was just about ready to starting excising them with ffmpeg.
Youtubers, the people:
Linus Tech Tips descends into thumbnail hell.
Reddit:
In 2017, reddit removed the word "(optional)" from the email field of their registration form, despite the fact that it's still optional. One justification is password recovery, the other is advertising and data collection.
reddit now places advertisements (oops, I mean, "promoted posts" (promoted by advertisers)) in line with real posts. I don't know when this started, but ads used to be relegated to the sidebar only.
Newreddit is designed mobile-first and media-first, designed for scrolling through images and videos on your phone. The Fluff Principle says that easy-to-judge content will dominate a vote-based system, and reddit is more than happy to enable that.
Newreddit has implemented a feature where clicking on the "X comments" link from a listing page will display the comment thread in a sort of modal, and clicking outside the modal will close the comments and show the listing again (in the SPA style where you've never actually navigated off the first page). They want it to be as easy as possible for you to bail on a topic and come back to the firehose laced with ads promoted posts.
Newreddit likes to show a measly two comments to logged-out users before suggesting that they redirect to another post, because dilly-dallying in the comments section doesn't make them money. This isn't on on some kind of overview page, this is on the actual /comments URL where you'd expect all 51 comments to be visible. This example gets bonus points for the fact that they're suggesting I leave a text post to see a fluff image post.
Moderators begged site staff for multiple weeks to have more control over the kinds of awards that can be put on posts, because some awards are being used to troll sensitive topics (one, two, three, four, five, you get the point). After hemming and hawing and espousing continued "support" and "appreciation" and "we hear you"s, staff have finally put the Yikes award on pause. Just that one, and not the others. It only took them an unjust death and nationwide protesting and rioting to finally lift their finger towards disabling a single source of income [32].
In 2020, site staff started an experiment that adds "award karma" as a separate karma category. "Our goals with this change are to recognize awarding as a key part of the Reddit community and to drive more of it, ... Awarding is an important part of our direct-to-consumer revenue; it complements advertising revenue and gives us a strong footing to pursue our mission into the future. By giving awards, users not only recognize others but also help Reddit in its mission to bring more community and belonging to the world". Oh, so that's what the awards system developers have been working on while ignoring all the other issues. Got it.
Video games:
Smart appliances:
"At Samsung, life runs through us. Your advertising should too."
No one knows the Samsung household better. Not even the families that live there.
Retail IRL:
Cooler Screens creates giant display screens that cover up the refrigerators in grocery stores so they can show advertisements instead of what's actually in the fridge provide the retail experience consumers want and deserve.
Other destruction of public space:
The subway stations in Toronto, Canada show advertisements on the signs that are supposed to help you find your train. The vestigial timing clock is relegated to a third of the screen.
Here's a fun comment from Hacker News user skizm that I wasn't sure where else in this article to quote:
I really do feel like there are two versions of the internet. One for people who aggressively use ad-blockers, pay for premium (non-ad) versions of things, manage their inboxes well, and generally are tech savvy enough to avoid 95% of unwanted advertising. Then there's everyone else who just accept the hundreds of ads washing over them at all times, that 60% of their screen real-estate is for ads, are completely comfortable with auto-playing videos, that are okay sitting through 30-second ads before watching a random funny video on youtube, etc. The second category can be sub-divided by motivations (some don't know there's a better way, some don't think it's worth the effort, etc.), but the resulting experience is the same no matter where you fall in group 2.
Here's the (a?) kicker: advertisers are willing to pay orders of magnitude more to get ads in front of group 1. They'll pour so many resources into it that they'll make everything "worse" for group 2. Group 1 adjusts their filters (both technical and mental), get back to neutral, but the rest of the internet is just a little worse off going forward because advertisers and publishers saw a very slight up tick in clicks after their scorched earth campaign to reach group 1. Rinse and repeat until we find ourselves where we are now.
I used to think that over time group 2 members would trickle into group 1, sort of like how programmers and hackers were using Google before it was cool and slowly the world followed, but that doesn't seem to be happening. Personally I'm seeing the groups continuing to divide. Group 2 really just doesn't see the problems, doesn't care, or isn't willing to put in the slightest effort to improve their interactions with technology and the internet.
My "favorite" outcome of all this is when a member of group 1 is forced to use a device owned by someone in group 2 and are horrified at what they see (favorite because it is equal parts sad and funny).
[32] You might think that reddit gold and their other newfangled abominations don't belong on an article about advertising, since it's a form of direct monetization for the site, essentially a donation. That's partially true, but the important difference between reddit gold and just donating money to reddit is the visibility of that golden badge. When you see someone else's post with a nice shiny gold on it, that's a prominent reminder that regular people, just like you!, can make a post so cool or funny that it earns a gold star from a total stranger. Gee whiz, if only I were that cool or funny! I'd better stay on reddit and keep trying until I get one too! Many young people will get sucked into the trap of striving for this pseudonymous congratulations and fame, and making ad impressions the whole while. As if the upvotes weren't bad enough.
I believe that the world is simple and there really aren't that many underlying, secret forces. The big things in our world are simply made of smaller things. Advertising is not an indivisible phenomenon that we can pack away into a clean little box and banish from society. It is an emergent property of incentives, game theory, Dunbar's number, psychology, information, trust, greed, and consumers who don't stand up for themselves. It is difficult to stamp out because it is a result of our natural traits.
But we have a lot of natural traits that we suppress in the name of decency or common good. We don't pee on the ground, for one. We have outlawed murder, burglary, kidnapping. We don't even allow child labor. These things are crimes because even though a few members of society benefit from them, the majority of society doesn't, and the majority got together and put it on the books. Advertising is similar. The beneficiaries are few, the violated are many, we just have to do something about it.
Some will say that banning advertisements is impossible because we run into challenges regarding the nature of free speech. What, am I not allowed to say I like a product any more? This is the kind of question people will smugly ask when you suggest that ads should be banned, because it's an easy strawman and the answer is no. I will continue to be in favor of word of mouth. But as soon as the brand starts paying people to say those things, or giving them free items in return, it's advertising. Others will say that there is no point in banning advertising since it would go underground and be hard to audit. To this, I remind you that we already ban other kinds of fraud and bribery, and I think it will be difficult for Coke to spend four billion dollars underground. The Pareto principle reassures us that we can make a big difference without auditing 100% of everything.
Outlawing advertisements, or at least clamping advertising expenditure, will not happen quickly. In the meantime, we as the public should block as many advertisements from our lives as we can, to reduce the amount of money the publishers and sponsors earn and drive them into the ground unless they get their act together. If they have any survival instincts, they'll come up with a new plan. If they don't, RIP.
I have said much about banning advertisements, or legislating limitations against them. Indeed, it is easy to sit back and pray that an abstract legislative force from on high will come and solve the problem for us. But I spent some time thinking about politics recently, and I want to say again here that there is no politics external from ourselves. We are the politics and we are the legislation. If you stop watching ads, and teach your children to not watch ads, and they teach their children to not watch ads, the next generations of politicians will be politicians against ads. Be a role model.
Please,
In discussions of politics, you will sometimes hear people say "if you don't like it, get out". This is a small-minded position, and if you've read the 23,000 words leading up to this point in the article, you probably don't say that. These people think that the past twelve thousand years of tumultuous human history have come to a sudden stop, and the present situation will remain static from here on out. Unlikely. In a sense, installing an adblocker is one part of "getting out". It is removing myself from the environment where I see ads. I did not need to write this article. I could have sat down and shut up and turned off my computer and stopped going outside, and I'd be "out". But I'm not content with that. The world is not static, it is going to change, and I'd like to contribute to the way it changes.
Are ads truly necessary for our survival? If everyone followed these steps, would the world grind to a halt, burst into flames, go up in smoke, go down the drain? There's only one way to find out! Follow your heart. Don't waste your time thinking about whether you have some moral obligation to watch an advertisement in order to keep the world functioning properly. If you don't want to see ads, then stop seeing ads. Let the rest of the world figure out for themselves how they're going to keep their blood pumping. Their income is not your responsibility.
Here's a message from Jackie Chan, speaking to filmmakers:
Whatever you do, do the best you can, because the film lives forever. "No, because, that day was raining, and the actor didn't have time...". Would you go to every theater to tell the audience? No! The audience sees in the theater: good movie, bad movie, that's all.
I think about this quote very often because it applies to every kind of published work and, indeed, our whole economy. As agents in a free market, we do not need to contort ourselves into sympathizing with whatever decisions led to the inclusion of advertisements in a product; we just need to say "bad movie" and pick something else. It is the seller's responsibility to make good work and earn our favor.
Here are my promises to you, reader.
If I come up with a program or website that I think is a worthy venture to make money from, I'll do so via one-time purchases, well-justified subscriptions, or donations, not advertisements. And as you know I publish plenty of what I make for free.
The website you are reading now will always be free of third-party ads. If your adblocker ever reports more than 0 hits, it's probably due to URL patterns or CSS names, so please let me know and I will fix it. Obviously this is a website about myself so in a sense I'm generally advertising myself, but it's your choice to come here and read about me.
I would like to try my hand at making videos from time to time again, and I have thoughts about getting into other forms of online media like podcasting or making short films. If and when I do, they'll be free of ads.
Will I ever work for a company that makes some of its money from ads? Almost certainly yes, since that's the state of almost every organization and unfortunately I can't let my idealism keep me incomeless. But I will seek organizations and positions that provide value to the world, and will avoid those that seem corrupt.
I started working on this article in March 2020, and I'm very glad to be through with it. It's one of the reasons I started writing at all. I've picked it up and put it down and felt guilty about not completing it too many times. One of the things I find difficult about writing is that because I spend so much time thinking about the topic, by the time I'm done I feel like the ideas are boring or lame. I have to remind myself that the creators of the stuff I watch and read probably feel the same way, and I should finish this article instead of sitting on it forever. I hope at least some part was interesting or new to you. Or maybe it is lame!
I honestly think that enforcing a maximum dollar cap on advertising expenditure is worth a try. I'm willing to accept that some amount of advertising is necessary for businesses to exist, and for me to be able to buy things instead of having to grow my own food and make my own furniture and invent my own internet; but we need to keep them on a leash. So many of us are sick of mega-billion dollar companies ruining the world and then publishing ads of smiling babies. The amount of advertising we are subjected to is not fundamentally necessary, and any claims that it is are pure spin. As they say "it is difficult to make a man understand something if his salary depends on his not understanding it".
Marry and reproduce.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I have a few long-running / daemon programs that I would like to "run as administrator" automatically when I start my computer, without UAC prompts. The programs are not available as Windows Services.
First, I tried placing an lnk shortcut in the Startup folder [1] with the "Run this program as an administrator" box checked. However, this didn't work, and I found that the program simply didn't start at all.
My next attempt was to use the Task Scheduler:
This worked, but the problem was that the task would be permanently stuck in the "task is currently running (0x41301)" state. So, I instead told the task scheduler to start cmd.exe with a command that immediately launches the real target program:
This solved the state problem because the cmd.exe finishes immediately, and that's all the task cares about.
The final problem was that the program would become slower and slower and slower over time. After a day of computer uptime, the program would be unusably slow. I found the solution to this problem here, which explains that scheduled tasks are started with below normal process priority. The fix (copied here for preservation) was:
<Priority>7</Priority>
with <Priority>4</Priority>
and save it.[1] %appdata%\Microsoft\Windows\Start Menu\Programs\Startup
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>[electronics] [today_i_did_this]
I have a wireless mouse that uses USB micro-B to recharge. I'd like for it to charge over USB type-C instead so I can use the cables that I already have around my desk.
It is a Vogek VKM42. You've never heard of Vogek and you never will again. I got the mouse for free and it is obviously very cheap, so I decided I wouldn't feel bad if I damaged it and the idea of replacing the socket was worth exploring.
There are two screws on the bottom underneath the gliders, which I cut so that I wouldn't have to fully remove them.
I didn't know where the screws would be underneath the gliders, or if the whole thing would simply be clipped shut, so I used some plastic blades to pry open the housing. The backside wouldn't pry, so I knew there were screws there.
As you can see, the USB socket only provides power to recharge the battery. The data lines are not connected because the mouse uses its wireless transmitter all the time. This makes the replacement very easy.
The type-C board that I used was conveniently sized to fit with the existing board. If you want to buy these, search for "USB type-C 2.0 receptacle". You should be able to find a 10-pack for one or two dollars plus shipping.
The micro-USB port was removed, then photographed with a shallow depth of field to make it feel unimportant.
The USB board has two intermediate solder pads between the socket and the wires. I'm not sure what they're for and the incomprehensible text didn't help.
I decided to assume they were unnecessary and soldered the type-C socket directly to the wires.
I plugged it in and it charged just fine.
However, I knew I needed to keep the other board because it has the screw hole which will keep the socket secure. I had to glue my type-C socket onto that board. I covered the old board with insulating tape to avoid short circuits and glued the pieces together with silicone, which I heard is good at bonding PCBs.
A minor disaster occured in which the white wire was decapitated.
I cut and stripped both wires and tried again.
The hole in the plastic housing was widened with a rotary tool to fit the type-C socket.
However, I had attached the socket to the other board with the fronts flush, whereas the original micro-USB socket had protruded from the board. My charging cables were not able to reach the new socket through the plastic housing. Not photographed.
I took the glue apart and tried again, this time with hot glue instead of silicone because the silicone took a very long time to become firm.
The problem with the hot glue attempt was that the glue made a very thick layer between the board and new socket, so it did not sit flush against the board. This took it out of alignment with the hole on the housing. Not photographed.
That didn't matter, because another minor disaster occured in which the red wire was decapitated. I was sick of these wires' weak heads and did a cranial transplant with some wire I could trust. I would have replaced them entirely but I don't have the metal bits to re-crimp a JST connector. So, I embraced the jank.
If you went into this article assuming I would know what I was doing, you were wrong.
I glued the type-C socket back onto the other board, first using superglue to tack them together, then adding the slow-drying silicone.
In the end, it works. I'm glad I got some practice on a low-stakes item like this, so that if I do it again on something else I'll be more prepared. One less micro-USB cable to deal with.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Note: when I first sat down to write this, I was expecting it to come out a little more structured and coherent. Instead it's more of a wild stream of consciousness and references. Sorry. If I had more time I'd have written a shorter something or other.
I used to tell people that I'm not interested in politics, or that I don't like politics. At the time, I thought of "politics" as elections, presidents, congress, bills, and laws, and I get bored hearing or talking about those things. That part is written in present tense because they still bore me, but the first part was past tense because I've since changed my understanding of what politics even is.
It's everything.
Or at least, it's everything that involves more than one person. Which is almost everything. Even if you live off the grid, totally isolated and self-sufficient, unless you're Tarzan or Nell and have never encountered another human being, you presumably left society to get there, and that decision was political.
Politics is how people interact with each other. Politics is deciding who deserves what, who gets what, and how and when and why they get it. Politics is making your decisions based on how you think other people might react. Politics is game theory. Do you follow someone's orders because they're in charge, or do you do what you believe is right? Do you anticipate that they will praise and congratulate you? How much does their opinion of you matter? Do you rely on resources they provide, do you need to keep them happy so they'll vote for you again next quarter, can you live without them? Politics is deciding how much to rely on others in the first place. Will they hate you, or ban you, or fire you, or torture and kill you? Do you have enough confidence in your decisions that you will preach to others and become a leader, or will you keep them to yourself and hope for the best?
Who you talk to is politics. Time is one of your most valuable assets, and who you spend it with is a big deal. It's good exercise to examine the relationships in your life and ask yourself what it is you get from them. There is always an answer. There are people you spend time with because they give you happiness and laughter, or physical intimacy. There are people you spend time with because you want to unlock future opportunities like jobs or travel or fame or fortune.
There are others you spend time with because you have a sense of obligation to do so, or a feeling of guilt if you don't. Maybe some family members come to mind. What you're "getting" in this case is a relief from that guilt. You can cut them out of your life if you really want to, but you'll have to power through difficult emotions to get there. Then again, maybe there's nothing wrong with having obligations sometimes. Maybe you have an abusive spouse or partner, whom you should escape from but whom you rely on for food and shelter. Maybe you fear the retaliation that will come if you try to leave them.
People Make Games did a video on a tabletop game called Tank Tactics that demonstrates the politics of interpersonal relationships very well. We already know that politics is big, but politics is also small. The situations that arise from a simple tabletop game with office coworkers are not unlike those that arise between real nations with real commerce and real nukes. PMG describes how some coworkers who used to be friends had stopped talking to each other. We love to scorn the race of people known as politicians, but every interpersonal conflict is going to see someone try to take charge. It's in our nature and it only makes sense to give it a name.
Morals are politics. Few things are inherently good or bad. It is a matter of interpersonal cooperation that theft, murder, and rape are illegal. To punish a stranger who hurt another stranger is straightforwardly logical because it deters others from hurting ourselves. But there are more abstract freedoms and crimes like dissent — illegal in some places because the people in charge are insecure and tyrannical — and pornography — illegal in some places because people like to make sure the world follows their vision of what's clean and correct. You might think it's silly for me to point out examples of laws and crimes and say "see, that's politics", but of course the morals came first and the laws came second. Then there are laws surrounding tobacco, alcohol, and other drugs, all caught in a dizzying mix of moral grandstanding, legitimate health concerns, and the fairness of health insurance payouts.
What you buy is politics. Products made locally, instead of in China, cost more. Products made without slave labor and animal cruelty cost more. Businesses that manage customer service domestically instead of outsourcing to India cost more. Televisions, computers, and cell phones that don't spy on you cost more. Electronics with removable batteries cost more, at least up front. Boots that last cost more. Every dollar you spend is a statement of your priorities and helps that company grow.
"Voting with your wallet" is a very tough thing that I'd like to write more about. A lot of it comes down to information imbalance and transparency since supply chains are so long and complicated now. It's hard to know where anything is made, and it's hard to know how good something will be before you buy it (the world needs more Project Farms!).
These days, big-budget AAA video games have a reputation for being broken, buggy messes on release day because the studios know that customers will complain but not actually do anything about it. I would love to see the look on a project manager's face if they woke up on release day and saw a big, fat, $0.00 on their sales sheets because the customers finally wised up. If only.
What you eat is politics. Folding Ideas has covered this in two great videos: Cooking Food on the Internet and Jamie Oliver's War on Nuggets. The traditional foods of many cultures are the foods that got them through times of poverty [1]. They represent togetherness not just in the geographical sense of eating what's nearby, but in a historical sense, a shared background and understanding. Even two mortal enemies can realize they have something in common when they sit down to eat the same dish. But in the same geographical region and culture, socioeconomic striations can be revealed through food. It is not just a matter of rich people having access to more expensive ingredients like caviar and truffles, it is an active avoidance or even a loathing for the foods associated with the non-rich that gives it away. Jamie Oliver's vendetta against chicken nuggets doesn't make me think he has fine culinary taste, it makes me think he's out of touch.
In America, many agricultural products are subsidized by the government. That is, the customer only pays a fraction of what the food really costs, and the government covers the rest so the farmer can break even. You will not be surprised to learn that some crops earn higher subsidies than others, making them cheaper for the consumer and ultimately influencing the diet of the entire nation.
Tradition is politics. Let's get the obvious out of the way and acknowledge that when countries undergo a major political event, it often becomes a holiday later. See America's Independence Day, France's Bastille Day, Britain's Guy Fawkes Day. But every other kind of tradition is still politics by virtue of gathering people around shared or not-so-shared values. I like what Folding Ideas says here too, so I won't even paraphrase: "Ritual is an outward signifier of stability", "they are things to look forward to, things to look back on", "the dueling desires of the human psyche: the need to be different, the need to be independent, but also welcome and accepted".
Traditions can be the source of controversy when people have conflicting opinions about what's valuable and worthy of preservation. See for example the Netherlands's blackface-wearing Zwarte Piet. Traditions are valuable to us because they keep historical events and ideas alive, but there comes a time when people decide that the value of upholding a tradition is not worth the tension it creates with modern sensibilities. The same can be said about statues and monuments representing immoral figures, propaganda art, and art by immoral people. Even if I personally am not offended by a certain thing, I can recognize when other people are, and make decisions about what I want to share and perpetuate. That's politics. And it's difficult to balance the removal of offensive material — because there's no need to lord statues of murderers over passers-by every day — with the preservation of history and knowledge — because forgetting those murders happened is a tragedy of its own.
Traditions evolve and are replaced as people mingle and migrate. If it's a tradition you don't like, you call this progress; if it's a tradition you do like, you call it erosion. Both Japan and North Korea have isolationism in their history books (and, uh, present day book) at least in part because the leaders got sick of foreign cultures interfering with their own. I was interested to learn that Korea took deliberate steps to remove Japanese loanwords from their vocabulary after the Japanese occupation ended. On the other hand, the number of English loanwords into pretty much every other language is actively growing. Mainland China does not recognize Taiwan as an independent nation, due in part to the fact that Taiwan preserved many artifacts and cultural elements that the CCP tried to destroy during the Cultural Revolution. It might be fair to say that Taiwan represents what China would have been, and the CCP hates having that reminder.
My family has some friends who own an alpaca farm. Some of their clientele are rich celebrities, who pay for the alpaca but leave it on the farm to be taken care of. Why would someone buy an alpaca in name only? Because the government allows the buyer to write that money off on their taxes. This incentivizes the flow of cash into the agricultural sector and helps preserve the tradition of raising a more diverse set of animals which otherwise might be displaced by pigs and cows. Tradition is political in the sense that it takes active, ongoing effort to maintain, and we as a culture decide how to carry that cost.
Travel and transit is politics. Whether you choose to walk, bike, ride, or drive is a decision soaked in your local politics. The kinds of infrastructure that exist, and to what extent they are developed, depend on the priorities of who's in charge. Since the 1950s, the U.S. federal government has provided subsidies of up to 90% [2] for the development of automobile freeways, allowing states to launch enormous road-paving projects for a tenth of the true price. San Francisco fought and won against a freeway development plan to protect their local identity and scenery. Paris, France is working to quickly beef up their bicycling network and get cars off the road. Countries tax the sale of gasoline in order to help pay for road infrastructure, which is about to become a problem as we switch to electric cars which use the road but not the gas. Even in a car-dependent area, you can decide to walk or bike as a way of making a statement of your values to your neighbors, but this statement will be costly in terms of your time and potentially your safety. Some of you will be willing to pay those costs, others will not. It is a catch-22 because cities usually won't develop alternative transit infrastructure if there is no demand, but there is no demand because the current state of non-car transit is bad. If you build it...? Lobbying is also a big issue with regards to the paradoxical state of car dependence.
Taxi medallions are government-regulated licenses for operating taxi cars. You can view them as a sign of authenticity and trustworthiness for the passenger, giving them confidence that they won't be axe-murdered by the driver; or as a form of artificial scarcity propping up a market segment that might collapse if exposed to the realities of supply and demand. It's probably both, although I've heard lots of stories about vile taxi drivers so maybe it's just the one.
Technological progress is politics. A lot of horses lost their jobs when the automobile was invented. I'm sure they had foals to feed. Upheaving the status quo and affecting peoples' current livelihoods in exchange for maybe improving the future is a politically hot move. When a robot takes a factory assembly line worker's place, should we celebrate because they've been liberated from a repetitive, boring, dangerous, or mindless job that squanders their potential as a human being; or fear because they might now go homeless? What if we, as customers and consumers, had voted with our wallets from the very beginning and never allowed a factory that puts people in assembly lines to become successful in the first place [3]?
The human mind is weird when it comes to progress. We have strong attractions to the first form of something that we encountered, even though our initial encounter was totally arbitrary [4]. If you gather up all the people who are against robotic automation of factory work, you'll find that very, very few of them are actually interested in going backwards in areas that have already been automated. There are no movements to reinstate employment of switchboard operators. To be honest, even my example of the assembly line is out of date since automation there is now so mainstream. Farm automation is a growing territory thanks to improvements in computer vision and automatic crop / weed differentiation.
Politicians love to run campaigns based on the idea of creating more jobs. If the notion of 'having more jobs' is noble in and of itself, we should be dismantling everything and turning them into jobs. The only reason this all matters so much is because the increased profits of automation are centralized amongst a few, and the pain and fear of being replaced are spread across the many. In a utopian society, these advancements would be uncontroversially celebrated as all of humanity would benefit from the awesome inventions we as a species can come up with.
Employment is politics. The employer wants to pay as little as possible, the employee wants to earn as much as possible. The employer gains an advantage when the employees do not know each others' salaries and will encourage a culture that is ashamed of talking about income. The power dynamics of employment are similar to large-scale economies: both parties rely on each other for something, but when the relationship is severed one party will fare better than the other, and they both know that. People love to hate their bosses; USA loves to hate China; people don't leave their bosses because they need the paycheck; USA doesn't leave China because we need the manufacturing. Employers can defend themselves from uppity employees by spreading out responsibilities and having new applicants on hand. Employees can defend themselves from uppity employers by keeping feelers out for new opportunities. It is a battle for leverage, for negotiating power. More primitively, employment is a sale of your time for the employer's money, but in every transaction there is the chance that one party will find a better deal elsewhere.
Most people don't like to change jobs very often, since that comes with its own set of headaches (paperwork, training, rebuilding personal rapport with coworkers, the desire to feel like you belong in just one place), but if your employer knows you won't leave them, they'll become more and more dominant in the relationship. Much like an abusive spouse who knows their partner is afraid to leave them, and for all the same reasons: food on table, roof over head.
Investments are politics. It's good to own a home because the value of homes always goes up. It's good to own stocks because on the whole stocks always go up. Anything that threatens the upward trend of housing prices is an existential threat to the owner — it might be the entire basis of their retirement plan and their only means of eating next month. I'm not even moaning about property speculators or prolific landlords — ordinary people rely on the cost of their homes through reverse mortgages. Value comes from scarcity, so it's existentially necessary for the homeowner to block the development of nearby affordable housing. Value comes from beauty, so it's existentially necessary to block power plants, wind farms, high-rises, and other infrastructure. See NIMBYism. Value comes from class and dignity, so it's existentially necessary to block the poor and the homeless and the racial minorities. See gentrification.
Throughout 2020 and 2021, the Fed propped up the stock market by buying bonds and securities with essentially unlimited funds. We expect unlimited growth and return on investment. We rely on the status quo and existentially panic when it doesn't hold up. There is the notion that all young people are liberal and all old people are conservative. We forget that investments are a form of gambling. We normalize this gambling and teach it to our children as the right way to live and to retire. According to the rules we've laid out for ourselves, these gamblers deserve to die of starvation and homelessness. But when push comes to shove, we realize we need to change those rules. Landlords were forbidden by the government from evicting tenants during the heights of covid. Stimulus checks went out to the tune of hundreds of billions of dollars. But we'll swear up and down we're not damn commies and this federal interference was just temporary. See also social security.
Everything is politics. I've covered all of the major topics that have been on my mind. As I proofread this page I feel that I have spent too much time on the negative kinds of politics and not enough on the positive. After all, if everything is politics, and some things are good, ∴ politics is sometimes good. But so far the words have been flowing easily, and going back to add positive thoughts is like pulling teeth, so, alas.
I want to end this article by condensing a thought that has been diffused throughout each of these sections. When we look at "politics", the global, legal, macroeconomic kind of politics that normally comes to mind at the word politics, we usually feel that it is too big and too separate of a thing to have anything to do with ourselves. There are politicians running my country, but I'm not one of them so I don't deal with politics. There are trade deals and manufacturing contracts and banking agreements, but I'm down here so I don't deal with politics. I can't change the world because the world is big and I am small.
But politics is present in even the smallest of interactions. Global politics is not fundamentally distinct from politics at any other level. It is the collection of every individual's small decisions, which has been growing for as long as humanity has grown. We see international leaders acting like immature school children, and for good reason: we're all actually doing the same thing. Every purchase you make, every idea you support, every employer you work for, all add up to this massive tiny thing we call politics. If you follow what you believe in, and do what you think is right, and encourage everyone you know to do the same, that changes the world by definition.
"I hear a million voices crying what can one man do?"
If you can carry this idea with you throughout your day, and remind yourself that you are thoroughly engaging in true, meaningful politics on an hourly basis all the time, maybe you'll feel a little less overwhelmed when you think about changing the world. You'll be used to it by then.
This article, like the others here, is moreso a compendium of thoughts than a statement of truth. I'm saying that so I can be off the hook for correctness. It's that easy! Maybe you have thoughts similar to mine and I've helped you think about things in a new way. Maybe your thoughts are opposed to mine, but at least now you know what kind of crazies you coexist with.
Boy, now I need to watch more Connections!
[1] Even if the food's reputation has since improved, e.g. lobster.
[2] "Until the 1950s, each federal dollar had to be matched by an identical amount of state and local money. The federal share is now 80% for non-Interstate System road projects and 90% for Interstate System projects. Generally, federal money can be spent only on designated federal-aid highways, which make up roughly a quarter of U.S. public roads."
[3] And don't tell me that it's impossible! It might be impossible while maintaining our current expectations of consumer comforts, but it's not impossible outright.
[4] I say "was arbitrary" and not "might have been arbitrary" because the deciding factor in all situations is when and where you were born, over which I don't think you had any control.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>One of the most effective ways to procrastinate on a task is to spend time working on something else that will supposedly help you do the original task more efficiently, but in actuality will never recoup the invested time. You can make a new tool, or design a new process, or rearrange your work environment, just as long as you spend more time on it than it could ever possibly pay you back. Whatever you do, never consult this chart. This technique will ensure that you come out behind on your goals while giving you the defense of having worked hard the entire time.
In this article, I'll show you a new tool I made.
Over the past three years, I've done almost 100% of my Anki studying on my smartphone, simply because I don't enjoy the ergonomics of using Anki on the computer. I don't like having to sit with my hands on the keyboard for a long time, pressing the spacebar. I'd rather be able to lean back or sit farther away.
At the same time, the ergonomics of the smartphone are not ideal either. The hands are most comfortable at the lap but this is bad for the neck. Researching words and copy-pasting unicode is slow and cumbersome on mobile.
I thought it might be nice to have a handheld controller that I can use with my computer from a distance. I already have an Xbox controller and joytokey, but if I used those things then I'd be done procrastinating already.
So there I was, with no choice but to make my own.
When I assembled my keyboard I used a microcontroller that cost $18 plus $5 shipping, which is more than I wanted to spend on a silly thing like the ankibutton. I happened to have an old rubber-dome style keyboard that was broken and useless, so I thought I'd take the controller out of that and wire up some of my leftover keyboard switches onto it. By following the sheets of electrical contacts you can learn which pins you'd need to solder switches to to make a keypress. I never did solder anything, but I used a piece of wire to connect some pins and figure out where the keys I want are.
I designed a case for this controller and three cherry switches.
I decided not to use that controller for two reasons. Mainly because it's not possible to reprogram the firmware on it, so if I ever got tired of using it as an ankibutton I'd be unable to change any of the keys without unsoldering and resoldering it in a new configuration. Secondly because I want to include a Ctrl+Z button on the ankibutton, and I don't think soldering a single switch onto the pads for both Ctrl and Z would work properly.
I set this idea aside for a few months until one day I got an idea for a different project and started researching for other microcontrollers. I discovered the Seeeduino Xiao, and was able to get a two-pack for $14. Seven dollars for an arduino-compatible board with USB-C is a pretty good price.
I also decided not to use the gateron keyboard switches, because for a handheld device these switches were just too big and would require lots of thumb movement during normal use. Instead, I harvested some small pushbuttons from a plate that had come out of a fax machine.
I redesigned the enclosure around the Seeeduino and 6mm pushbuttons.
I used superglue to hold the buttons in place, and double-sided tape to fix the controller in its recess. I used doubled-sided tape to attach a piece of felt on the underside of the lid, so that when the lid is firmly shut it provides more support to the controller.
The wiring was straightforward, though I'm still not very good at soldering. The idea is the same as a full-sized keyboard matrix. One wire comes out of the controller and visits all four switches, providing what I am calling the "outbound" signal. Then, the other leg of each switch is wired to a separate pin on the controller so that there are four distinct "inbound" signals. The controller simulates a keypress whenever an inbound signal is received.
I was surprised to find that the Seeeduino does not support QMK firmware like I used on my keyboard. Or at least, I was not able to make QMK Toolbox discover the device even after switching the MCU type to atmega328p. I had to write the firmware myself as Arduino code which took me a while but was overall not too difficult.
Programming for hardware is slower than programming computer software. Normally when I write a program that crashes I can just read the traceback, but in hardware there are no tracebacks. It just stops working. And I have to keep bisecting the code until I find the part that does the least amount of wrongness, each time using a piece of wire to short RESET to GROUND to go back to bootloader mode because regular mode crashes before Arduino can reprogram it.
Even though the first several prints I made were able to snap shut with a bit of friction, for some reason the final one didn't hold itself together very well. But I was tired of printing it so I wrapped it with some blue tape instead of doing it again.
My original plan was for three buttons: Spacebar (right answer), 1 (wrong answer), and Ctrl+Z (go back). After switching to the little buttons it made more sense to have four. It would be nice to map it to Anki's "easy" answer, but that's not straightforward since easy is sometimes 3 and sometimes 4. I am not quite sure what I'll do with it yet.
The finished product functions very well. With a long USB cable I can lean back and review my flashcards comfortably. I added code to debounce the button presses and they seem reliable.
Having said that, I will probably use the ankibutton a few times and then forget about it. The burden of plugging it in, or worse, leaving it plugged in and cluttering my desk space, is simply higher than the value it provides. Mission accomplished!
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
.When the Seeeduino is in normal operating mode, it will occupy one COM port. If you use a piece of wire to short RESET to GROUND twice in a row, it will enter bootloader mode and occupy a different COM port. During bootloader mode it will also appear in Windows as an external storage device.
When uploading the code from Arduino IDE to the board, it will automatically go from normal mode to bootloader mode and back again. But if you need to reset it manually due to a crash, you need to go back to Tools > Ports and pick the bootloader port before uploading again.
I found that uploading the code would often make my computer reset all of its USB connections, including my external hard drives, which was problematic for me. I did the remainder of the programming on a separate laptop to avoid this.
At first, my laptop was not able to recognize the device at all. I had to download seeed_usb_serial.inf, and then tell Device Manager to install a driver from that file. When Device Manager asks for a driver location it only allows you to select folders, not files, so just select the folder into which you downloaded the inf file.
After these steps I did not encounter any more issues with programming the controller.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>[electronics] [today_i_did_this]
Here is a Motorola C139 cell phone from about 2008. I rediscovered it in a drawer last year.
The charger for this device has long been misplaced. It uses a barrel plug smaller than any I've ever seen, with an outer diameter of about 3mm.
I thought it would be fun to turn this old phone back on just for nostalgia's sake, but without the charger and not wanting to tear it open to access the charger pins, I just put it back in the drawer.
Here is a TP4056 battery charger that I bought on ebay a few weeks ago to explore another project idea.
While I was fiddling with it, I realized this might be just what I needed to get the Motorola working again.
And that worked! This thirteen year old battery is still able to take a charge.
The only problem now is that the phone is really boring to use and I have no purpose for it. Other than to play breakout.
P.S. I accidentally fried this TP4056 shortly after taking these photos. I picked it up with the wires still dangling out of those pins and I think I shorted something. Smoke came out and everything. Luckily it came in a two-pack.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In April, I wrote operatornotify.py, a module which allows my programs to notify me of important information or errors. I was immediately very proud of it. It felt awesome to get so much impact out of a sub-100 line module as I went around hooking it up to my existing programs and getting the tracebacks from my horribly broken code delivered right to me.
Since then, I have figured out which parts of the interface are most important, and boiled them down into a single decorator, so that adding @operatornotify.main_decorator
is all it takes to get emails from a program. It's probably the best bang-for-buck code I've written in a while.
@operatornotify.main_decorator(subject='myprogram.py')
def main(argv):
...
if __name__ == '__main__':
raise SystemExit(main(sys.argv[1:]))
The most important part of operatornotify's design is that it takes advantage of your existing logging infrastructure. Although you can call operatornotify.notify
whenever you want, it's much easier to add a log handler that captures WARNING level messages automatically. This has encouraged me to revisit some older programs that just used print statements and replace them with proper logging, which makes them easier to use and debug in general.
There are a few pain points that arise from using operatornotify as a log handler. For example:
When using @main_decorator
, you have to pick a subject line ahead of time and can't change it later. But to improve the skimmability of emails in my inbox, I like to prefix the subject lines with ⭕︎
if everything went okay [1] and ✕
if there was a warning, which obviously is not known until the end of runtime. I can imagine a few solutions but haven't decided which is most clean and appropriate for inclusion in the module [2].
Not all messages cleanly fit into the integer levels of logging. For the programs I run as scheduled tasks, it's nice to receive some kind of message to know that they ran successfully and didn't just fail to launch, but I don't necessarily want to see all of their output since I trust the returned status of 0. So neither --operatornotify-level WARNING
or INFO
is really ideal.
But these inconveniences are vastly outweighed by the ability to add a single decorator function that immediately supercharges all of the existing log lines and encourages me to add better logging where I skimped on it earlier.
Then I took the next step towards this summit of email enlightenment: running the mail server myself. I figure there are three reasons I should self-host the mail for operatornotify:
The notifications usually contain private information or filepaths that I don't like to have sitting on a third-party server. I don't think these worries are justified since my email provider does at-rest encryption and uses SSL, but I just don't like it.
My code might wind up sending hundreds of emails in a row, and I don't want to do that to a third-party host.
It's a good chance for me to play with stuff I haven't tried before.
I'm using the Maddy email server, which is an all-in-one solution for both SMTP and IMAP. I also considered Mail-in-a-Box, but their documents specifically say that it's designed to have the whole machine to itself, which I don't want to do. The most widely known software is Postfix for SMTP and Dovecot for IMAP, but I started drowning in the configuration of dovecot before even touching postfix, and gave up. I'm just a single user emailing myself. I like that maddy is just a single binary. So now I'm free to send myself as many thousands of emails as I want, containing whatever I want, using my own code and connecting to my own server.
FairEmail on Android supports IMAP IDLE, so I can get tracebacks anytime, anywhere. It's great.
Here are some ways I'm using operatornotify:
My computer emails me after it boots. I configured the BIOS to automatically turn the computer back on after a power outage occurs, so I have an email letting me know roughly when that happened and what to expect next time I'm back.
My OVH server emails itself after it boots. Then, it launches a few programs — etiquette.voussoir.net, /u/Newsletterly, etc. — and emails again me when all of those have finished starting and the processes appear in pidof
. If I accidentally break something in my Python environment that prevents those programs from working, I'll know about it before too long.
Most of my task scheduler jobs use --operatornotify-level WARNING
. A lot of repetetive tasks that I used to do manually are now fully automated, but if they experience any errors (usually just network timeouts or 503s), I can re-run them at my convenience.
I'm working on a daily "system heartbeat" email that gives me a rundown of all the daemon processes that should always be running, and all of the task scheduler jobs that ran throughout the day. Although adding operatornotify to a program can help me get its traceback, it doesn't help me when the program is totally broken and didn't even launch. For example, when I upgrade Python and forget to pip install
a module, so the ImportError
occurs before main ever runs. I'd rather not add an intermediate launcher that tries to launch the task and notifies me if that fails.
For the record, the code that actually sends the emails is in my my_operatornotify.py
. The basic code you need is:
import email.message
import smtplib
def send_email(subject, body=''):
sender = 'xxx'
recipient = 'xxx'
subject = str(subject)
body = str(body)
message = email.message.EmailMessage()
message.add_header('From', sender)
message.add_header('Subject', subject)
message.add_header('To', recipient)
message.set_payload(body, charset='utf-8')
server = smtplib.SMTP_SSL('xxx', 465)
server.login('username', 'password')
server.send_message(message)
server.quit()
def notify(subject, body=''):
...
send_email(subject, body)
...
But I have some additional stuff in there to deal with retrying and eventually writing the message to my desktop if the mail server is unreachable.
To write the system heartbeat, I'm parsing the output of schtasks
with the subprocess module:
import csv
import subprocess
from voussoirkit import winwhich
command = [
winwhich.which('schtasks'),
'/query',
'/tn', '\\voussoir\\',
'/fo', 'csv',
'/v'
]
output = subprocess.check_output(
command,
stderr=subprocess.STDOUT,
creationflags=subprocess.CREATE_NO_WINDOW,
)
output = output.decode('utf-8')
lines = output.splitlines()
reader = csv.DictReader(lines)
for line in reader:
...
[1] I wanted to use a checkmark, but the fonts on Android make all of the unicode check marks look stupendously ugly. And Android doesn't let me change the system font outside of Daddy Google's approved list because I'm a big stupid dummy baby who can't be trusted with a ttf because I might get a boo-boo.
[2] I am using a stopgap solution in my_operatornotify
that detects the phrase "Program finished, returned 0" to add the ⭕︎.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I use Sublime Text as my EDITOR
environment variable and as my git editor. I used ST2 for many years and recently jumped to ST4, skipping 3. But something has changed along the way, or maybe it was always a little imperfect.
Between Sublime's workspaces and project sessions and hot-exit files that allow you to close with unsaved changes, there is quite a lot of state saved to disk. I found myself getting frustrated at the various incantations of sublime_text.exe -n
, sublime_text.exe -n -w
, subl.exe -n -w
because they recalled the previous state and opened a bunch of tabs or windows when I just wanted to do a single git rebase.
Here is a forum thread where other people have the same problem, and they mostly discuss workarounds through config files. I didn't want to make any of those changes because I like having all my tabs restored in 99% of cases, just not for temporary EDITOR
purposes.
Then I realized something that I should have realized a long time ago because I'm the one who's always going on about it: Sublime is portable software. I can just make a copy of the folder. And I did. And it's great.
Now, I have C:\Software\Sublime Text\4133
and C:\Software\Sublime Text\4133_EDITOR
, and I can configure them independently. For the EDITOR copy, I can remove all project folders, disable a lot of UI elements, turn off state-saving, and uninstall unnecessary packages.
My EDITOR
environment variable is C:/software/sublime text/4113_EDITOR/subl.exe -n -w
.
My .gitconfig contains:
[core]
editor = 'C:/software/sublime text/4113_EDITOR/subl.exe' -n -w
My WinSCP editor is C:/software/sublime text/4113_EDITOR/sublime_text.exe -n !.!
.
Use portable software, folks.
P.S. I found that the -w
flag only waits if you also provide a filename to edit on the command line. subl -w
does not block, but subl -w myfile.txt
does block. This made me confused while I was testing everything.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In May of 2021 I discovered the youtube channel Not Just Bikes, and immediately watched the whole thing. The experience was revelatory and painful.
NJB has shown me that American urban and road design took a nosedive during the postwar period, where the American Dream was to own a house with a yard, drive a car everywhere you go, and, for some reason, have nothing of utility around you. It's very easy to hop around a map of the US and find houses where the nearest grocery store is literally an hour's walk away.
So you drive, and you park in the parking lots. The parking lots are enormous because everybody's driving instead of walking. They're so enormous, they push all the actual destinations farther and farther apart from each other, so that walking becomes even more useless and you have to do even more driving. Then the parking lots have to get bigger.
It would be no big deal to visit several small stores for a few items each on foot, but nobody likes starting their car multiple times to visit multiple stores across an asphalt ocean, and finding a new parking space each time. So, shopping trips are usually single-destination only, preferring the Walmarts and Targets over the small, specialized, personalized, and/or more informed grocers and boutiques.
Our stroads are wide, straight, and multilaned, so that it's easy for us to go really really fast and crash into buildings, because those are our priorities. All other forms of transit infrastructure are designed first and foremost to avoid disrupting the fragile egos of the motorists:
Because heaven forbid we impose upon the helpless motorists inside their cushy, air conditioned, noise-proof boxes, with radio and navigation and heated seats, that require no physical effort to launch at speeds higher than humanity could have dreamed of just two hundred years ago. Don't make them wait at a crossing. Life is already so hard for them.
Here's my favorite NJB quote:
For centuries, cities were designed such that everybody had what they needed within walking distance. Once you got where you were going, you could access everything you needed to on foot. These are the kinds of places Americans go to on vacation.
He says "centuries", but I think he means "since the dawn of civilization". Automobiles are less than 150 years old. You might recognize a number of beautiful, comfortable, enviable cities which are older than that. And you'll never find yourself thinking "commuting to work in ancient Rome must have been so difficult without a car!", because it wasn't. The car didn't become a necessity until we intentionally stamped out all of the alternatives.
In America, young people love to say that the DMV needs to be more aggressive with re-testing elderly people and revoking their drivers license because they cause more danger in traffic. And while that's true and probably a good idea, it doesn't get implemented because license revocation is a prison sentence and absolutely everyone knows it. In the cities of respectable nations, children and the elderly don't have any problems going to the shop or cafe on their own because it's only five minutes away from their front door. In the States, a car is compulsory for all travel unless you live in the very densest of areas. Without it, you're stuck. Taking away your grandmother's license is taking away her independence. A whole lifetime of stars-and-stripes 🦅 American 🦅 freedom and independence comes toppling down with the removal of that one stone. Then Grandma spends the rest of her life trapped in the house because there's nowhere to walk and not enough bus service and everything's too far for even an electric mobility scooter to be useful, and she whithers away into mental and physical atrophy and dies.
One of the first excuses that springs to peoples' minds as to why America must be car dependent is that it is so big. Yes, America is geographically big, and if you go looking you can find very isolated cities that would take a long time to travel between. But the width of the continent as a whole has absolutely nothing to do with the placement of essentials within a single city. Even people who own very large houses still keep the toilet paper within arm's reach of the commode.
The people who built the oldest parts of our country must not have known how big the continent was, because they put living quarters right on top of shops back then! If today's cities would suck in their gut and bring more mixed use back into the center of downtown, people could get all of their daily business done by walking instead of driving, regardless of the center-to-center distance between them and the next city over. It's a non-sequitur.
The phrase that's been in my mind for a while is "too stupid to live". It is something of a wonder that we Americans haven't already extinguished ourselves by forgetting how to breathe or eat. You may have heard that sloths can starve to death on a full stomach because their only source of food is practically indigestible. You'd think they'd figure it out and try something else.
When my family gathers around the dinner table, one topic that always comes up for conversation is the vehicular idiocy that was seen throughout the week. Red light runs, excessive speeding, drivers in the shoulder lane, crashes, and near misses. A majority of people are not to be trusted with the task of driving, but we force them to do it anyway because we, collectively, are too stupid to put together better systems that don't necessitate it. It is easier to concentrate our moments of frustration towards the individuals who make short-term mistakes like running red lights than it is to realize the frustration that should be directed at the makers of long-term, diffuse, and pervasive mistakes like building suburban sprawl and bulldozing transit options.
Another part of the problem is that it feels good to punish people. We are a sadistic species and we like to coerce people into crossing our boundaries so that we can feel justified in retaliating. It is not as fun to design boundaries that don't get crossed in the first place. We design roadways that encourage unsafe driving and then we put up signs justifying punishment. It's dissonance. Here's a big fat 50mph five lane road that runs straight for miles, but you'd better slow down to 25mph now because there's an elementary school here. Nevermind that the 25mph stretch of road is cut from the same cloth as the 50mph road — it's the posted sign that makes the difference. Here's a series of traffic lights that don't coordinate with each other, and will stop you over and over again just as soon as you get going, but you'd better not run any reds and you sure as hell better not get stuck in the intersection during a light change because boy I'm gonna, um, honk at you, yeah that's what I'm gonna do, and you're gonna deserve it. It is difficult to convince people that car crashes are a symptom of deep, systemic design flaws affecting average people of average driving skill, rather than the fault of uniquely stupid individuals. Which is not to say the average skill level is very high, but even the people who'd like to opt out do not have a choice.
There is a freeway near me that is currently undergoing expansion, which is proven to induce more demand. Intelligent species have known this for decades. The mbillions of dollars being used to put more cars on the road are not being used to improve walkability, bikeability, or reduce the need for driving in the first place by fixing our wack zoning and just allowing a grocery to open on more corners.
Our zoning is the first thing that must change before anything else can happen. American cities are designed with huge contiguous swaths of land zoned as residential, especially R1 which denotes single-family housing. This is the zoning that prevents you from walking to the shop because there are no shops. This is the zoning that requires you to exodus by car to do absolutely anything except admire your neighbors' yards. This is the zoning for which every American deserves forty lashes.
With mixed-use zoning we can allow destinations to exist among the living space instead of being wholly separate. We should start with small shops, cafes, and restaurants. The kinds of things that are needed often by the residents and won't draw excessive traffic from far away because the people who live far away have their own. This will give the NIMBYs less room to complain, though they will try anyway.
In the study of occupational safety, there is something called the hierarchy of controls. Commonly represented as an inverted pyramid, it suggests you should do everything you can to eliminate a hazard using the most effective methods available to you, and only proceed to less effective methods when absolutely necessary. In between each of these levels, you could insert the phrase "but if you can't, then, ...".
For example, an electrician wearing rubber gloves (PPE) could touch a live wire without too much risk, but it makes a lot more sense to turn the circuit off in the first place (Elimination) unless there are substantial justifications for working hot.
Applying this to suburban motorsports, we might find these levels correspond to:
Fail, fail, fail, fail, pass. Great job America, you got seatbelts in your cars. The only measure you've managed to accomplish so far is the least effective.
We are the sloths. We are too stupid to live. We'd rather challenge ourselves with the invention of self-driving cars and the manufacture of unspeakable quantities of batteries for EVs [1] than consider the possibility that maybe spending thousands of hours in traffic isn't an inherent part of life around which all else must bow down. You'd think they'd figure it out and try something else.
NJB has made me ashamed to be American. I am ashamed that a country with this much flagrant disregard for sense touts itself as the best nation in the world. I am ashamed that the closest we can get to eco-friendliness is to make our cars run on massive batteries and steer themselves, because simply getting out of the car was never considered an option. I am ashamed that these are my surroundings and that I did not wake up from this Matrix sooner.
One of the other big problems with cars, which I don't think NJB has mentioned yet, is that they turn everyone into anonymous metal bubbles. Even without tinted windows, cars provide very little person-to-person visibility, communication, and most importantly, empathy. It is easy to become hateful towards a driver on the road in a way you'd never be towards a person you bumped into on foot, because they are nothing more than a big hotwheel that's sitting in your way. Also because bumping into someone on foot doesn't normally incur thousands of dollars of property damage.
Tom Scott made a video about Peachtree City, Georgia [2]. They have a network of asphalt paths designed specifically for travel by golf cart, which I think is really cool and sets a good example for the rest of the country to follow. Small vehicles provide an intermediate option between bicycles and 3,000 pound automobiles, ideal for many of the around-town trips we have to make where a bike might not be enough:
NJB has talked about microcars, and while the video is still excellent, these don't strike my fancy the same way the golf carts did. Most of the microcars shown in his video follow too much in the design language of regular cars, with their high pillars and rectangulish porthole windows.
If we were to adopt small vehicles in more areas, I'd like them to remain mostly open-air, or wrapped in clear glass only. Slower modes of travel allow everyone to be closer to each other, and this coupled with high person-to-person visibility will ease traffic interactions and lessen the visceral savage hate that leads to so many of our stupid, pointless crashes. A switch to small vehicles is an opportunity to solve multiple traffic problems at once — let's not squander it by following the same old metal-bubble design. I don't expect actual golf carts to be what sweeps the nation, I just want small vehicles about that size, plus some comforts like weatherproofing and some speakers.
(See also Micah Toll's glowing review of a 25 mph electric mini-truck from China: part 1, part 2)
Finally, we need more public transit and it needs to provide benefits that cars can't. Sometimes I'll pick a destination on Google maps and ask it to route by transit. For destinations that are within "day trip" distance, the results are usually three to five times as long as travel by car, blowing all possibility of making a day trip out of it. I tried sampling a few destinations from here to the other coast and transit never seems to break even, always 1.5× to 2.5× the travel time of the car.
I have very little experience riding transit, so I'm not sure how much timing overhead is to be expected, or if these numbers are Americanly bad. Naturally, some time overhead is worth it in exchange for not having to do the driving, and transit routes can never be as direct as driving there yourself. But I really was expecting the trains to go just a little bit faster to make up for it. Notwithstanding that at these distances you're better off enjoying stops along the way rather than gunning for the finish.
As it stands, it is undeniable that transit is always significantly slower and less practical for day-to-day travel than driving except in the very densest of cities, and only exists for those who have no other options. Improved transit could be a great benefit to our society and atmosphere [3], but only if it provides enough advantages to be desirable to a person who otherwise could drive a car.
I can also recommend City Beautiful. In the meantime, try breaking traffic waves.
Here's an exchange from How to Get Ahead in Advertising, a movie I'm surprised I hadn't heard of earlier:
- [Dennis, to his boil] I'd like to see you suffer.
- [Boil] A typically communist statement.
- I'm not a communist!
- Yes, you are. You want to take everyone's car away.
- I do not want to take anything from anyone. I want to give them the choice of something better.
- Oh, yes? What?
- Trains.
- Trains? Trains are no good. They're old-fashioned. I hate trains. They're rotten.
- Only because they don't consume. Only because they're already there and don't eat up more and more and more. That's why you hate them. That's why government hates them. That's why they're old-fashioned and rotten.
- You commies don't half talk a lot of shit.
- Shut up! I'm not a communist!
And here's a fun, angry comment from Hacker News user brailsafe:
The suburbs are ironically, but not so surprisingly filled with crazy assholes that feel like the world belongs to them, or otherwise have some absurd levels of entitlement. They feel like they own the sidewalks, or if there's no sidewalks, they own the street and everything on it or not on it in front of their house, they feel like they should control whether or not a marginally higher density building should be built down the street or whether a neighbor can paint their house a different colour. When there's no land left, they want more cul-de-sacs built for them because it's the suburban dream and fuck wetlands anyway, and when there's no social services left, they want new ones built for them at everyone else's expense and they don't really want to be part of a community; they want to be by themselves, on their fat asses, in front of their fucking TV, the only quality of which they understand is how big it is.
[1] I look forward to EVs replacing ICEs, but they are still not as good as just using fewer cars.
[2] not to be confused with...
[3] That's the place we keep our breathable air.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Hi! 👋
It looks like you're viewing this post in a web browser. Posts from voussoir.net look better and have more features when viewed from our official voussoir.net app! That's because we've intentionally reduced the performance and functionality of the web version, which would otherwise do everything you need! So although you seem to be very content browsing the website, we've decided to cut you off, block your scrolling with this modal, and serve 429s for the remainder of your session. Trust us, this really is for your own good. We just can't stand to see you suffer through this non-optimal voussoir.net experience when you could be using our awesome app instead. Thank us later!
(No thanks, I hate myself and I don't deserve the best voussoir.net experience!)
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I am interested in IPFS. I don't run a node, but I look forward to seeing the technology grow. I like peer-to-peer networks and hope they make a strong resurgence.
However, IPFS has marketing problems. I am subscribed to /r/ipfs which is inundated daily with posts by people who have clearly gotten the wrong idea about what IPFS is and isn't, and the IPFS homepage hasn't exactly stepped up to clarify the misunderstandings.
All of the quotes in this article are real posts from /r/ipfs or other forums:
Won't there be hard drive capacity isssues if everyone used IPFS?
The way I understand it is everyone who opts in to be an IPFS server will download all the content on the web that I browse to, and host it.
Would it be a good idea to make an ipfs mobile app
They have made a web browser plug-in but I'm wondering if it would be a good idea to somehow make an app for your mobile device that works with ipfs maybe something you could use to sync your contacts but then again to run into the same problem you would need somebody to run the gateway node for you I mean I have 64 gigabytes of storage on my phone but I don't think it is enough to run and ipfs Gateway on there lol I had a computer with a 2 terabyte hard drive and it managed to fill that thing up in less than a week I Can Only Imagine how fast it could fill up 64GB
Any way to get an mp4 to loop infinitely when uploading to IPFS?
After uploading content on the IPFS network and having its relative CID address available, that content and address will never be more removable or editable, correct?
IPFS Soundcloud. How would one upload an audio file to IPFS through the browser?
I am new to IPFS and javascript programming in general. I am trying to build the barebones beginnings of a "Soundcloud" clone that can live and stream entirely from IPFS.
I was able to get the streaming working but even after reading documentation, I'm having trouble figuring out how to implement uploading. I know there's a method to ipfs-add a file.
I thought when you upload something on IPFS it is stored across all nodes on the network. What makes it different from centralized services? How to know who are using IPFS that is global and won't get down?
Is it a good idea to store avatars for my project on IPFS?
I want to use the least amount of money for my project as a challenge so I was wondering if it was possible and is a good idea to store avatars (around 2-8mb) on IPFS and use an API to access them later.
How does ipfs avoid spam and bad actors?
What if I would try to upload several petabytes of data, what would prevent me doing that to overload the current network?
I heard that any node will host also a bit of other random ones, what can have illegal things. Am I totally safe for using IPFS?
Hey guys I decided to spin up own IPFS node.
Works perfect in docker 24/7.
Some questions:
How permanent are IPFS uploads?
The number one problem with IPFS's public perception is that a huge, huge number of people think that IPFS is a place you just "upload" to, and it'll hold your files forever. People see the word "decentralized" or "distributed" and assume that IPFS distributes your files for you, for free, everywhere.
IPFS is a peer-to-peer system, comparable to bittorrent. You are a peer, and you host files so that other peers can download them from you. When you use the "import file" button in the IPFS client GUI, or the ipfs add
command on the CLI, you are simply telling the rest of the world that you have a file you'd like to share. It doesn't actually get uploaded anywhere until another person asks you for it. That's because IPFS is not a place you upload to, it's a network you're a part of.
Most end users are not accustomed to being an equal, active participant in the great glowing mass we call the internet. We feel that 'the internet' is this big thing that is separate from ourselves, managed by far away entities with billions of dollars. We are accustomed to interactions between service providers: Google, Apple, Facebook; and service users: us. We upload photos to Facebook and then leave. We upload videos to YouTube and then leave. The internet just runs 24/7 and I don't have to do anything about it.
Proportionally, the number of people who have ever hosted a web server or game server for their friends, or transferred files between two devices in their home via LAN IP is dwindling all the time. Instead we rely on web hosting companies or "official" game servers and we forget that this power was ever within our grasp. Recently I explained to someone that a modem connects your house to the internet and your router connects your devices to each other — and they asked me why you'd want to do that. The word "internet" means "between networks", and necessarily postdates the smaller institutional- and home-level networks we started with.
You can be a part of the World Wide Web even if you don't own a domain name: just run an http server program, open your ports, and give your friends your IP. You're live. Welcome to the internet. It's made by people, and you're a people too. You can even run a website off of a cell phone, except that Google and Apple are making this harder all the time in order to groom your Stockholm syndrome.
To be a part of IPFS, you need to download and run the client software, either on your home PC or on a rented server, and allow other people to connect to you. Then you need to leave it running, because if you turn it off then of course nobody can get your files. What did you expect.
The selling point of IPFS — the nature of its decentralization — is that anybody who downloads your files can seed them to anyone else using the exact same link. The ipfs://
links contain the hash of the file rather than the address of your computer specifically.
This is the difference between IPFS and the regular HTTP web: if a video gets deleted from youtube.com, it's possible someone else in the world made a copy, but how are you going to find that person? If you get lucky, someone will generously reupload it, but the link will be different and hard to find. And if that link gets deleted, you need to find another one. Over and over again. With IPFS, the original link works as long as a single person in the solar system is willing to keep it alive.
There are companies or entities known as pinning services, who will host your files on IPFS for you if you pay them. However, even this is not "uploading to IPFS" any more than uploading a file to Amazon S3 is "uploading to The Internet". The agreement to host the file in exchange for money is between you and the service provider. IPFS the protocol and the IPFS community at large aren't responsible if that host goes out of business and stops hosting your file.
Who pays for the storage on IPFS?
I keep coming back to the same question, who pays for the storage space. Like I can create a local node and upload my draft-version2-history report but why on earth would that be getting replicated across the network. It's great for me because now I can globally access it, but who would want to store that file solely for me who didn't pay anything for that replication?
What stops ipfs from becoming a tragedy of the commons?
I look at my own hard drive and half the contents - perhaps most - is ephemeral, intermediate, or junk. Sometimes I'm forced to sift through Everest-sized piles of digital rubbish to reclaim disk space, though in the process I inevitably lose some of the baby along with the bathwater.
Now imagine all that cruft on a planetary scale, petabytes of obsolete memes, shopping lists, programs in the process of being developed, temporary files — and billions of idiots who pin them all someplace else as a free cloud backup.
If I run a node on my home server, how many terabytes do I reserve to replicate an infinitely expanding pin list, assuming I only have to host the content I offer or have previously downloaded?
What makes you think you can just "pin them all some place else as a free cloud backup"? Most pinning services charge you per GB*month (or equivalent) for the things you pin. If you stop paying, they stop pinning it.
I just want to be sure I understand the objective — is it fundamentally a gimmick to part rubes from their crypto, or a genuine innovation in distributed storage?
ipfs has nothing to do with bitcoin. Its just an alternative to http. its a way to share data that is not inherently centralized.
I expect most or all cluster providers will require or at least allow payment by means of their preferred wankcoin, don't you?
What's the difference between storing files on AWS cloud and IPFS?
From this subreddit, I learned that IPFS does not store your files permanently even if I pinned them. If so, why should I store on it? So that my files can't be hacked? So that in case Amazon goes bankrupt I still have my files? But if I use a pinned service like Pinata.cloud, they might go bust too.
If I host my own node, how to ensure that the file I uploaded goes into my node?
I learned that files are not forever on ipfs and the best way to make them permanent is by hosting my own node. So, if I do host one, do I just redirect my files into my node or will ALL nodes have ALL files from around the world from everyone?
Cos otherwise, if all my files are only in my node then what's the point of decentralization.
What's the point of IPFS? Why wouldn't I just host the files myself?
From what I understand, IPFS isn't private, your IP is public, and nodes only host the files they want to host.
Since most people only care about their own stuff, most files will be hosted from a single machine with a public IP.
Why wouldn't I just host the files from a single machine with a public IP?
What is IPFS actually providing?
I am grappling with a similar question, how can we incentivize fellow nodes to pin our data? Is there any quid pro quo proposal or protocol in place?
Okay so if no one pinned anything and just hosted what they host then it would be just like the internet without IPFS. So what incentivises people to pin?
Incentive seems to be one of the fundamentally unsolved problems for decentralized storage. Not only does hosting content need to be profitable, but there needs to be systems in place that make sure that users aren't just hosting the same popular content that gets the most traffic and dumping less popular content because it isn't generating the same amount of revenue.
This misconception often stems from the first, that IPFS is a giant magical hard drive in the sky where other people will hold on to your stuff for you forever, so naturally there must be some big incentive for them to do that. "What's in it for me?" is the only language we understand. That was the idea behind Filecoin — it gives members a financial incentive to share their storage space with the network. As it happens, Filecoin operates on a completely separate peer network, unreachable by the regular IPFS client, since they need to keep their accounts payable in order. Yet, people conflate Filecoin with IPFS itself, and assume that all IPFS involves the use of Filecoin or other payment, because they can't fathom what sort of incentives exist besides financial ones.
There is no "push" mechanism in IPFS. There is no forcing people to take a copy of your stuff if they didn't specifically ask for it. The IPFS homepage says "each network node stores only content it is interested in".
That's right, idiots. Nobody's going to help you replicate your history book report for the same reason that they won't let you put your lawnmower in their garage after your garage gets full. They're not interested. This shouldn't be surprising.
This is related to the previous idea, that people are only familiar with online services backed by faceless corporations. It's difficult to imagine that the system is made of actual people and you have to make it worth their while to download what you're sharing. That's the magical effect of money, of course: people will suddenly become interested in your homework assignments and lawnmowers if you pay them to be. But in the absence of the financial incentive, you are left with the fact that nobody else is interested in your random junk files.
For many of these people, the line of reasoning stops there. If the network won't host my stuff for me for free, it's pointless. Ok, bye. Meanwhile, the people who generate valuable data that is interesting and desirable to others will see their files propagate. If NASA started advertising CIDs for original moon landing footage, there would be plenty of volunteers replicating it.
Many of these comments assume that all other IPFS nodes are strangers, but why? IPFS can very well be deployed in an organization where no one is a stranger to each other, and they don't need financial incentives to host each others' files. A website operator could serve their javascript or image assets over IPFS, and put lots of IPFS nodes around the world so that visitors can connect to the nearest one. If random strangers want to pin the assets, they can do that too, but the website owner would always know that keeping their files alive is their responsibility. They would never rely on strangers' pins when the functionality of their website is at stake.
Here is another example: imagine that a team of researchers in Antarctica (or on Mars) are accessing a website over IPFS. The first researcher will have to download the page and its assets over a slow satellite connection that leads back to the original node, but then they can seed the files to the other researchers over a faster local network. These peers are incentivized to help each other because it leads to a better experience for the whole group, not because they're getting paid.
The point of IPFS is not "strangers keep my stuff", it's "people sharing files" for whatever reasons they need. You just have to look past your own nose.
Why do we need decentralised/censorship resistant communication platforms when they already exist on darknet?
they probably aren't decentralised but they do the job
Can my uploaded IPFS files be traced to get my IP address?
I'd like to use IPFS to share my files with others on Discord, however I'm concerned someone might grab my IP. Is this possible, and if it is, how do I protect myself from being attacked?
I love the idea of decentralized file storage, but how would IPFS prevent something like the distribution of child porn or hate speech?
What is stopping someone from creating a child porn IPFS website?
What are the ways in which ipfs prevents piracy?
I was thinking that all the successful decentralized networks today are highly utilised for piracy which harms the reputation of the technology. So what are the ways in which ipfs prevents that and what are the disadvantages of those implementations?
What Prevents IPFS from becoming the next uTorrent?
I believe this a problem that IPFS will face as in any peer to peer network, piracy is a big issue.
I propose that we make a "hash blacklist" which will have a list of hashes which are illegal. Though we would have to build a proper system around it and make sure that not any or every hash is added to it, kinda like a dmca takedown.
I want to join the IPFS, but I'm concerned about ending up with illegal content on my computer somehow. I tried to find information about this on the web but haven't been successful, so I thought I'd ask here.
I don't want illegal movies, music, etc., but I'm especially concerned about illegal sexual content like child porn. Having even traces of that stuff on your system could be disastrous. So, if I get involved in the decentralized web, and particularly with IPFS, how do I protect myself from illegal content?
What stops people from distributing illegal copies of different types of media?
(1) If I were a bad person and started uploading pirated copies of movies or games, what stops someone from doing this?
(2) If I have the legal rights to a movie and I found an illegal copy on IPFS for free. How could I prevent this from spreading; or stopping this illegal activity from happening? I guess this wouldn't be possible as the whole point is to spread data around so people can download it even if the original uploader is offline.
You can find lots of posts from people who are worried about illegal or unsavory things happening through IPFS, and much of the messaging surrounding IPFS does describe it as "unstoppable" or "censorship-resistant" or "can't be taken down". There are a couple of angles we can get at here depending on your concern.
Some of these people believe that IPFS is a place you upload to, or that all nodes assist with the hosting of all files, which leads them to believe that by running an IPFS node they will wind up with illegal files on their computer. There is precedence for p2p networks where all peers help host all files, like GNUnet and Freenet, but this is not the case with IPFS. You only host what you visit and pin.
On the other hand, some people might just feel generally uneasy knowing that child molesters can use new tools like IPFS to share their material, and they wish the system had some kind of innate block against that. But how do you expect the IPFS software to know whether a file is being blocked for a "good" reason, like preventing the spread of child pornography, versus a "bad" reason, like preventing the spread of Tiananmen Square photos? Both of these situations are basically the same: it's material that people are not allowed to look at. It just depends who's doing the allowing and disallowing in your jurisdiction. Should there be a human-curated ban list built into the default client? Curated by people from which country? The client is open source anyway, so criminals could compile the program without the blocklist. It just doesn't work. Using technical solutions to address social problems rarely does.
You'll also notice that knives do not have special handles that prevent you from committing murder, beer bottles do not prevent you from driving drunk, cash does not prevent you from buying drugs, pens do not prevent you from forging signatures. The tool is agnostic and the crime is up to you.
What stops people from distributing illegal files over IPFS? Nothing. IPFS is just a protocol. It is a language that two computers speak when they talk to each other. There is no sequence of words in the English language that will instantly alert the police when I say them, no matter how bad the words are. Likewise, there is no kind of file that will cause IPFS to alert the police.
However, (here comes the point of this section), IPFS is not anonymous. When you run an IPFS node and people connect to you, they're connecting to your public IP address assigned to you by your internet service provider. If the police catch wind of any CIDs for illegal files, they'll just check out which IP addresses are sharing those files and try to pin down the owners of the IP addresses.
People have begun to conflate decentralization with anonymity, which is not correct. As I described earlier, companies decentralize their CDN servers because it improves regional latency, but they are certainly not anonymous. Networks that aim for anonymity like Tor or I2P do so by routing your connection through several intermediate nodes so that the sender and receiver never talk directly to each other.
If a journalist in China tries to publicize the Tiananmen Square incident, the Chinese government might discover it and try to shut that person down. But, because a single ipfs://
link can work anywhere in the world, that journalist only needs a single friend outside of the country to also pin the file and make it available globally, then the journalist can turn off their node. Other countries like USA will not prosecute a person for hosting the photos. (Realistically, the journalist should transfer the file to their friend through a separate, encrypted channel, not IPFS, in the first place.)
As with other technologies, like bittorrent or even just http, you could gain anonymity by running the program on a far away server which you rent or by diligently routing your PC traffic through a VPN. In both of those cases, you still need to make sure that the server owner or VPN service won't hand you over to the police and that your payment method doesn't lead back to your real name. The person who wants to download illegal files should prepare for the possibility of connecting to a honeypot source, and they probably should remove the file from their IPFS node afterward so it doesn't seed back to anyone else. This is already standard procedure.
From what I've seen so far, the censorship-resistance claims of IPFS are predicated on the idea that you're first able to get your files out of the jurisdiction that wants to censor them and into a jurisdiction where they're permitted. IPFS does not provide any secrecy, and if the whole world is after you, IPFS isn't a magic shield. The fact of the matter is that the regular HTTP web already carries hate speech, copyrighted files, and illegal material, but new protocols are subjected to higher scrutiny and criticism than the incumbents as a matter of course.
Now, one of those comments I quoted made a great point, which is that the reputation of the technology as a whole can be ruined if it's known for piracy or criminal material. Bittorrent is known for little other than piracy — when people give a demonstration of how to use a bittorrent client, they always show how to download a Linux release or Big Buck Bunny, because that's the only thing they can think of that isn't a copyright violation. Many people think that torrents are inherently illegal. So far, IPFS hasn't become a popular piracy tool to my knowledge, and all of their messaging centers around webpages.
Am I doing a good job so far? Let's compare what I've written with what appears on the IPFS homepage to see how poorly they communicate their project to newcomers. All of the statements they make are technically correct, but they only make sense if you already know how IPFS works. If you don't, it's problematic.
Note: since this article was originally published, some phrasing on their homepage has changed. This is the revision against which I wrote these criticisms. I will keep this article as-is until I take the time to review the new claims.
Today's web can't preserve humanity's history
The average lifespan of a web page is 100 days before it's gone forever. It's not good enough for the primary medium of our era to be this fragile. IPFS keeps every version of your files and makes it simple to set up resilient networks for mirroring data.
To the layperson, this implies that 'the network' stores your files forever once you put them in. It does absolutely nothing to address the mindset that most internet users have, which is that service providers and service users are clearly delineated.
Have you heard the phrase "guns don't kill people, people kill people"? Well, the network doesn't store anything, it's the people that store things, and IPFS is the network by which you can reach them. But people can get bored of holding on to a particular file and delete it to make space for something else.
Are you still holding on to copies of all the webpages you read 100 days ago? No? Why not? Don't you want to contribute to the permanence of all those pages? I clutch my pearls in your general direction. See, it's easy to sit around fawning over IPFS for being 'the permanent web' until you realize that permanence isn't actually a guarantee of the protocol. Permanence is a possibility, only to be realized by the collective choice of individuals to host the material they believe is important. And unless you're doing your part to preserve and host the files you think are important, you don't have much ground to stand on when you find that other people aren't keeping the stuff you want either.
Archivists
IPFS provides deduplication, high performance, and clustered persistence — empowering you to store the world's information for future generations.
Similar to the previous one, the word "provides" here gives the wrong impression to people who approach this page with the mindset that IPFS is a web storage service like DropBox. I'm not saying that's the only possible interpretation, but it's a very common one and IPFS should write more clearly to disambiguate.
"IPFS provides me with high performance storage? Sure, I'll take it! What? No, I don't want to actually run anything..."
I will give them credit for "empowering you to store", giving agency to the reader. Just make sure you use the power once you've got it.
Blockchains
With IPFS, you can address large amounts of data and put immutable, permanent links in transactions — timestamping and securing content without having to put the data itself on-chain.
This doesn't mention the fact that the link is only good as long as someone keeps the file. When everyone assumes "oh, the network's got it, I can delete mine", you'll suddenly find there's no copies left. By omission, this implies that IPFS just holds things forever.
Here's how IPFS works
Take a look at what happens when you add a file to IPFS.
Wording here could be changed to "when you add a file to your IPFS node" to remind that you're processing your own files; this isn't happening remotely on some kind of IPFS service.
Your file, and all of the blocks within it, is given a unique fingerprint called a cryptographic hash.
IPFS removes duplications across the network.
This statement isn't specific enough. I get it, because two identical files will produce matching hashes, so you don't get "duplicate" links. But removing duplications sounds like the opposite of what the reader wants — high availability and low latency are achieved only after many duplicates of the file are shared by many peers around the world. By contrast, it is the centralized file hosts like Google Drive who benefit most from file deduplication: if two people upload the same file to GD, Google can just store it once and let both people download it, saving themselves disk space. IPFS's statement almost lends itself to the interpretation that files will be removed from your node if they already exist on someone else's, which isn't the case.
Furthermore, this statement uses third-person voice for both IPFS and "the network", which is a double-whammy against the agency of the reader. It sounds like a remote service.
Each network node stores only content it is interested in, plus some indexing information that helps figure out which node is storing what.
Could be reworded to "You only store content you're interested in" to remind that IPFS is not a remote service and give agency to the reader.
When you look up a file to view or download, you're asking the network to find the nodes that are storing the content behind that file's hash.
This is weird. "Asking the network to find the nodes"? That's like asking the wave to find the water. What is the network if not nodes? And the sentence structure reminds me of the dog that killed the cat that caught the mouse that ate the cheese.
Should be reworded to "you're asking your peers to find who has a copy of that file".
Content creators
IPFS brings the freedom and independent spirit of the web in full force — and can help you deliver your content at a much lower cost.
The IPFS copywriters should be aware that approximately 100% of today's content creators are accustomed to uploading their videos, music, photos, and blog posts to online ad-supported services without having to pay to do so. You probably should let them know that hosting their creations on IPFS requires them to run a node or pay a pinning service, and that the decentralization only happens after they have fans who are willing to store and pin their works.
IPFS's homepage is bad. I wonder if they are intentionally toeing the line with their messaging, since the implications are always more grandiose and fabulous than the reality. I've said it once and I'll say it again: sqlite.org has a front-page link to When to use SQLite which also plainly describes when not to use it. IPFS doesn't do this because they're not as chad as SQLite. Can't fault them for that. No one is.
Clearly, IPFS's messaging, and the messaging from crypto nuts who advocate IPFS without really knowing what it is either, has led people to believe that IPFS is a giant decentralized cloud storage system that may or may not be free to use. In my opinion, the copywriters need to turn this ship around and make it clear that IPFS is not a magic dumping ground for your random personal junk to be replicated globally. It's a peer-to-peer network that you need to actually participate in if you ever want to get anything done.
Welcome to the internet.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>
I've wanted a mechanical keyboard for a long time, but have never been happy with the options available to purchase. The main reason, as trivial as it will sound, is that I prefer the Home/End block of keys to be arranged vertically. The standard arrangement is horizontal, and I've never seen a mechanical keyboard with the vertical arrangement.
This alone was enough to get me interested in building my own keyboard, but I put it off for a long time because I knew it would be expensive. Finally, I've gotten around to it. The solution to price anxiety is to start buying some of the parts before calculating the total cost of the project so that you can tell yourself "Well, I can't stop now!".
The result is not perfect, but it's nearer.
I find myself leaning towards the word "assembling" rather than "building" for this project. I have been continuously amazed at how much work the keyboard community has put into the resources and tooling that make assembling a keyboard honestly very easy. Everyone has coordinated around the keyboard-layout-editor data format which makes the transition between each tool at each step of the process totally seamless. Really, I feel like I didn't do a whole lot except for the soldering. But we'll get to that in a bit.
The only actual hard part is making the choices — switch type, plate material, base material, layout, keycaps. You'll see people talk about the sound, feel, and resonance of each part, but it's hard to tell the difference on their videos.
This article will be a mixture of build log, diary, and tutorial. It's a bit long-winded and over-detailed, but that's because I have a new keyboard I need to break in so I want to type a lot. Maybe you'll find something here that other build logs omit. I hope it is useful to somebody.
The layout was designed with keyboard-layout-editor.com.
This is the final layout of Nearer:
[{x:1.5,a:7},"F13","F14","F15","F16",{x:0.5},"F17","F18","F19","F20",{x:0.5},"F21","F22","F23","F24",{x:0.25,sm:"cherry"},"Scroll Lock","Num Lock"],
[{x:0.25},"Esc",{x:0.25},"F1","F2","F3","F4",{x:0.5},"F5","F6","F7","F8",{x:0.5},"F9","F10","F11","F12",{x:0.25},"Print Screen","Pause Break",{x:0.25},"A/한","한자"],
[{y:0.25,x:0.5},"~","1","2","3","4","5","6","7","8","9","0","-",{w:2},"Back",{x:0.25},"Home","End",{x:0.25},"Back","/","*","-"],
[{w:1.5},"Tab","Q","W","E","R","T","Y","U","I","O","P","[","]","\\",{x:0.25},"Insert","PgUp",{x:0.25},"7","8","9",{h:2},"+"],
[{w:1.5},"Caps Lock","A","S","D",{n:true},"F","G","H",{n:true},"J","K","L",{a:5},":\n;","\"\n'",{a:7,w:2},"Enter",{x:0.25},"Delete","PgDn",{x:0.25},"4",{n:true},"5","6"],
[{w:1.5},"Shift","Z","X","C","V","B","N","M",{a:5},"<\n,",">\n.","?\n/",{a:7,w:2},"Shift","=",{x:2.5},"1","2","3",{h:2},"Enter"],
[{y:-0.75,x:14.75},"↑"],
[{y:-0.25,w:1.5},"Ctrl","Win","Alt",{w:6},"Space","Alt","Menu",{w:1.5},"Ctrl",{x:4,w:2},"0","."],
[{y:-0.75,x:13.75},"←","↓","→"]
Here's how the layout evolved. I started by drawing my previous keyboard, a Logitech Classic Keyboard 200. It's just a regular $10 office keyboard, but it's the one responsible for my obsession with vertical Home/End.
F13-24
The whole reason I started this project was so that I could have my vertical home/end block, but I felt I should come up with some more customization ideas to justify the time and money. Well... I wouldn't mind having a dozen more F keys to bind, so let's go with that.
Ortholinear
I wasn't originally interested in ortholinear keyboards, but I saw this video by Ben Vallack and was convinced to try it out. Watching this video is like watching the mask come off a Scooby Doo villain. It would be one thing if the traditional QWERTY stagger matched the natural curvature of the hands or something, but the stagger leans in the same direction for both hands. There's just no excuse. So while I'm not ready to commit to a true ergo layout with staggered columns or split halves, I'm willing to make the ortho switch. I'll admit, despite all the time I've spent typing, I'm still really bad at reliably hitting numbers on the number row. Ortho should make that easier once I know that 4 and 7 are above F and J.
KP-Backspace
I always hate when I'm reaching for End or numpad-slash and accidentally hit Num Lock, so I knew from the beginning I'd be moving Num Lock and putting a backspace in its place. That meant putting Num Lock up with Scroll Lock, which makes for a nice 2×2 arrangement. The best part is that Print Screen and Pause/Break are the only ones I plan on pressing regularly [1], so it's nice to not have Scroll Lock in between them.
A/한
I gave myself a dedicated English/한글 toggle key so I could stop relying on my Alt+Menu AHK script. The AHK solution works perfectly fine, but I would occasionally blunder the Menu keypress and be left navigating the toolbar of the current application thanks to the Alt press. I put it next to Right Shift because why is that key so long in the first place.
Shift-equals
I was having a hard time fitting the Equals button between Minus and Backspace without reducing Backspace to 1u or taking 1 and Q out of alignment, which I wasn't willing to do. I decided to put it next to shift, and while I knew it would take some time to get used to, it's not unreasonable. That's right, I'd rather break my muscle memory on the equals key than on the home/end block. That's how dedicated I am.
This meant moving A/한 above the numpad. The downside is that this is a much farther reach, but the upside is I have plenty of room up there for a 한자 key too, which I wouldn't have included otherwise. Realistically, I could just map Ctrl+A한 to 한자, so if I ever come up with another need for that key that's what I'll do. You know, after I use up all 24 F keys.
Although I liked the idea of the 1.25u Ctrl giving the left edge of the board a sort of curvature, I found during prototyping that pressing hotkeys is much easier with a 1.5u Ctrl because I tend to strike the leftmost edge of the Ctrl key, especially now that A and Z are physically closer to the left edge of the board — the hand posture for Ctrl+Z is much tighter on this layout compared to the original.
Speaking of hand posture, let's compare the ortholinear layout with the traditional stagger more closely:
By far the biggest letter changes are on the Z row, with each key moving 0.5u to the left. You can see how much Ctrl hotkeys have changed now that the 0.75u horizontal gap is completely gone. For the first few weeks of using this keyboard, I was constantly overshooting my copy-pastes.
The Q row feels almost identical, and I'm happy to report that the 1u backslash is not giving me any trouble. The number row is almost a full 1u farther to the right now, which is mostly not a problem since I don't feel like I ever really internalized the old stagger anyway. However, underscore did give me a hard time since it's almost a full 1u to the right from where it used to be, and now neighbors backspace. Equal has definitely taken some getting used to, but I've got the muscle memory for it now.
[1] Pause is used to pause commandline applications, and Ctrl+Break is used to kill commandline applications that aren't terminating on Ctrl+C.
The layout has 118 keys, and I knew I wanted a few spares of each size. I went with 140×Gateron Yellow from KBDFans and 129×blank black PBT caps from NPKC.
For as long as I've been thinking about buying a mechanical keyboard, I've always imagined I would choose Blues for the clicky sound. But, I read various forum threads about clicky vs linear and saw that a lot of clicky users find them to be a nuisance after a while, or felt that actuation pressure should be learned by muscle memory instead of pushing through the click. Some day I'm sure I'll do another keyboard and I'd like to try clickies eventually, but I decided to do linear Yellows this time. Although typing on the linears isn't exactly quiet, you certainly can press keys silently if you need to. The typing experience is perfectly pleasant, and after only a few days of using the Nearer I found my rubber dome keyboard terrible in comparison.
Ordering the caps was kind of weird. The AliExpress page has product variant buttons for "100 pcs", "200 pcs", etc., but the seller has their own pricing scheme outlined in the product description. You're supposed to tell them what keys you need and they'll calculate a price by considering 2u keys to be 2× the price of 1u keys, and so forth, and that's how many "pieces" you need. Well that's not what AliExpress's variant ordering system is designed for, so I'm really not sure how this was supposed to go down. I just chose the variant that was close to, although a little bit less than the value that I calculated, and they accepted the payment without question. So I guess I got a discount. Your results may vary if you need pieces that aren't close to any of the variants.
Another thing I didn't expect is that the homing keys don't have raised bumps on them. Instead, the surface of the key has a deeper indent than the rest. Visually, it's very hard to distinguish, but in practice I'm not having any trouble with them.
I've got 22 switches left over, either to use as repairs or just to play around with. I also made sure to buy at least two extra of each cap size.
For the controller I chose the 24-pin Elite-C V4 because I wanted to use USB-C. That's pretty much the only reason.
The switchplate is made by taking the output of keyboard-layout-editor and pasting it into builder.swillkb. I chose an 8mm edge padding, 8mm edge radius, and a couple of 2.1mm holes so I can use 2M screws.
If I were to do this again, I'd give myself a little more padding between the screw holes and the edge of the plate, and I'd add more intermediate screw holes. My switchplate has a very slight bend to it and I don't have any means of making it perfectly flat, so a few extra screws would help me get the plate to sit more flush against the base.
Because this layout would be totally new to me, I knew I needed to be comfortable with the design before having it cut in metal. I bought a foam posterboard, printed the layout on paper, and spent about four hours across a couple of podcast-listening sessions to cut out each switch hole with a craft knife.
I'm sure you're wondering about the gray spacebar. This was in fact the result of spontaneous inspiration, an experience not much different from true enlightenment, which came to me after an intense bout of deeply personal meditation and was fully crystalized when the keycap vendor said "We don't have 6u space in black, only in gray".
This prototype was definitely worth the time, because this is the point where I changed Ctrl from 1.25u to 1.5u. If I hadn't bought extra 1.5u caps, that wouldn't have been possible.
After generating the final switchplate on swillkb, I had it cut through LaserBoost. Swillkb has a partnership with LaserGist, but I found that LaserGist's price before shipping was about $20 higher than LaserBoost's price after shipping. I tried comparing a few other options, but most either don't have instant price quoting or the prices weren't any better than LB.
Switchplates should be 1.5mm thick for Cherry-style switches, which includes the Gaterons.
While the plate was still in the mail, I started working on the wiring matrix. This was the first time I had ever put together a piece of electronics and it was a great learning experience.
Each key switch has two posts on the underside. Keyboards are wired with one post connected to a "column" wire and the other connected to a "row" wire. The controller sends signals out via the column wires, one column at a time, and listens to the row wires to see where the signal comes back. In effect, every key has an X, Y coordinate which the firmware then maps to letters / keycodes.
A simple matrix for my keyboard would look like this:
But, there's a problem. Each of these wires needs to be soldered onto a separate pin of the controller, which means the controller must have at least rows+columns
available pins. That means I'd need 27 pins, but the Elite-C only has 24.
The solution is what's called a duplex layout, where two physical columns are wired together as a single virtual column. Here's mine:
The duplex layout halves the number of columns in exchange for doubling the number of rows. That brings me to 10+14=24 exactly. This does mean I have no pins left for Caps Lock or Num Lock LEDs. Instead, Caps Lock is indicated by pushing a button and seeing a capital letter come out.
If you're willing to sacrifice your sanity to achieve maximum keyboarditude, the maximum number of keys you can address is (pins/2)²
— a 12×12 matrix with 144 keys in this case. You might have to do some gymnastics with your wires, since the physical layout would be far removed from the virtual layout, but it would be possible. Keep in mind that the controller doesn't know or care about the physical positions of the switches, as long as each one has a unique X, Y coordinate via the row and column wires.
Anyway, here's the wiring diagram as seen from the underside, which is how we'll actually work on it, and in more realistic detail:
And the wires join up to the controller like this:
You're seeing the final versions of these images, but make no mistake — this took several iterations to get right. In fact, while I was soldering the wires I realized that I had imagined it differently and just changed the design right then. You can optimize your controller pin mapping to reduce the length and overlaps of your wires, but it's not a big deal. Whatever happens, you can adjust the firmware to match whatever you put together.
If you've seen other keyboard builds, you'll know that the wiring matrix requires diodes. I bought these 1N4148 diodes.
I know what diodes do — they allow electricity to only flow in one direction — but it took me a bit of studying to figure out how that applies to keyboards. I put together this drawing to illustrate my findings. In this picture, the black keys are the ones being pressed. Remember that the controller sends a signal out through one column at a time and listens to the rows, so here's C7 being lit up:
The signal from the column wire is transfered through the switch and diode to the row wire, telling the controller the row coordinate of the pressed keys in the C7 column. The controller sees R11 and R14, so the pressed keys are C7+R11 and C7+R14, 7 and 0.
If your keyboard doesn't have diodes, certain combinations of keypresses can carry the signal to places that trick the controller into believing some other keys are being pressed when they actually aren't. Notice how the signal is flowing through the 9 key in the wrong direction, from a row to a column, which lights up the C9 column. Even though 6's actual coordinate is C9+R12, the controller only knows that it sent a signal on C7 and got a response back on R12, so it thinks C7+R12 is pressed, which is 4.
The plate was still in the mail at this point, and I felt confident about the wiring design, so I began doing the firmware on kbfirmware.com. Once again, the keyboard community has done all the hard work. All I'm doing is plugging in my information.
Not so fast, kbfirmware. Don't you know we're doing a duplex layout?
Yeah, that's right, that's just how I like my duplex layouts.
As it happens, kbfirmware uses the exact opposite red/blue color scheme that I chose, but you can see how those diagonal jumps represent the long bridges I drew, connecting two physical columns into a single virtual column.
I drew my controller diagram with row and column numbers starting from 1, but on kbfirmware they start from 0. Filling in this table is a good workout for your looking-back-and-forth muscles, often underrepresented in other workout routines.
After downloading the firmware as a .hex file, it is loaded onto the controller using QMK Toolbox. It did everything perfectly on the first try. Just turn on auto-flash, and use a paperclip or piece of wire to short RESET to GROUND twice to reset the microcontroller.
Then, you can simulate keypresses by shorting a column pin to a row pin. And you can just end the whole project here, really. The rest of the keyboard is basically just decoration. It's functional as is.
The switchplate came in the mail:
But something must have been wrong with the laser that day, because the plate had some alignment defects to the tune of 1mm in a couple of places. Normally I'm not one to complain to support, but this was expensive and beyond their stated tolerances. I took some pictures demonstrating the alignment with a ruler and some MS Paint annotations:
LaserBoost immediately offered to express-mail a replacement for free. So in the end everything turned out fine.
I wouldn't want to miss this opportunity to show off how I transfered the switches from the first plate to the new plate. The cap- and switch-pullers I ordered in the mail wouldn't arrive for at least another month.
That's right, everyone. When you buy cap- and switch-pullers for $1.00 on ebay, you're giving in to Big Puller's brainwashing. Paperclips and tweezers were all you needed all along.
When you press the switches into the plate, they make an audible click. The plastic body of the switch is shaped so that it grips the plate from below. But I couldn't shake the feeling that someday I'd be pulling a cap off of a switch and have the whole switch rip out of the plate, bringing a spaghetti dish of wires along with it. As fun as it was to put this together, I really, really don't want to have to do any repairs. I decided, for better or worse, to reinforce the switches with a whole bunch of hot glue.
WARNING: You're supposed to put your stabilizers in the plate before your switches! My stabilizers were in transit for more than a month by this point, so I just went ahead without them. I was able to add them retroactively but it wasn't ideal. See #Stabilizers.
Speaking of firsts, this was my first time working with hot glue. It's interesting stuff. I think if you use it once you'll either instantly hate it for its awful, stringy messiness; or you'll instantly love it for its versatility and speed.
In the following photos, you should be able to identify three distinct stages of how it went:
I ran out of hot glue. But, this dark period of my life was short-lived. I bought more glue and got back to work making angels cry:
Finally, with the plate ready and switches set, it was time to begin wiring.
I began with the columns. I was hoping I could use a single strand of wire to connect the whole column, stripping off little gaps in the wire near the posts for soldering, but at this time I couldn't figure out a good way to do that. So, the linkage between each switch was done individually. I wound a bit of wire around each post, and in fact did a dry fit of the whole board before soldering anything.
This took a long time.
I linked the duplexed columns, and held them down with tape since these long wires tend not to want to sit still.
Then I began soldering. This was my first time soldering, and I think I did pretty alright.
Next, I did the diodes. As you can see from the diagram, the diodes are soldered to the other post and reach down to the row wire. The black ring around the diode indicates the front, and should point away from the switch towards the row wire.
I found that using the plate itself as a bending guide for the diode tails was perfect for helping me wrap them around the posts.
Unlike the column wires, I didn't dry-fit the whole board, because the other tail of each diode reaches down to the next one. So, I did dry fits and solders for each row, bottom to top.
This took a long time.
Next up was the rows. Remember how I wanted to strip the middles of the wires when I was doing the columns? Well now I was extra motivated to find a solution, because doing individual wires for the rows would mean three-way joins between each row segment and the accompanying diode, and I didn't want to deal with that.
I found that I could use the soldering iron to melt away the insulation from the wire. This was very effective, but in retrospect was a BAD IDEA because it made the tip very dirty and difficult to solder with afterwards. More crimes against humanity. Sorry. I was able to clean the tip by repeatedly burning solder onto it and wiping it off, which burned away the rubber residue.
This took a long time.
The downside of the duplex layout is that R1-R7 need to reach allll the way over to the controller, so I tried to route the wires between the keys and keep it looking nice.
The underlying ocean of hot glue proved its worth by helping me seat some discarded pieces of diode tails, which I used as guides to stop the wires from flying around all over the place. Seriously, it's impossible to totally straighten a wire like this, so they always fling themselves to one side at every chance they get.
I hope you're ready for more hot glue crime because I've got more hot glue crime.
I didn't want to glue the controller directly to the plate for two reasons. First, if for any reason I ever need to remove the controller, I don't want to be prying it off the metal and breaking anything. And second, I want the plug to be approximately centered along the backside of the keyboard base — not pressed directly up against the top. So, I did a little bit of manual 3D printing with everyone's favorite polymer.
And finally, I could make the last solder joins, from all the rows and columns to the controller.
I had been trying to keep the wires nice and pretty up to this point, but some of these final linkages just required inconvenient wire paths. R7 had to get over and across the controller, and C1-C6 had to come down at an angle. Oh well.
It works! I made some firmware changes to accommodate the change I made during wiring, and also fixed some keycodes that I had chosen incorrectly (the `/~
key should be KC_GRAVE, because KC_TILDE always types ~
even without shift, etc.)
I wanted to make the base out of a dark piece of wood, or at least wood stained dark. My grandfather has a workshop, and in fact he's the one who built my desk, so I went over to his house and we put something together.
On my own time, I brought the height of the base down, drilled the screw holes, and added a hardware reset button to facilitate easier experimentation with the firmware. The plug and reset button holes required a couple rounds of adjustment, and as a result don't look very good, but I'll consider it a learning experience. The piece of wood which goes over the plug hole is dangerously thin as it is, so I can't experiment with the shape any more. There's nothing stopping me from unscrewing the plate and making a whole new base if I choose to. Except for the fact that this one was made with my grandfather and will someday be a family heirloom.
Then I did the stain and other finishing touches, and screwed the plate down.
This section shouldn't be last, but it is.
My keyboard uses a 6u space, which is uncommon. The standard size is 6.25, which of course would not fit in the ortholinear design. There are fewer vendors selling 6u space stabilizers, and they are all in China / Taiwan. I found a set on ebay, ordered them, and waited. And waited. And waited. UPS had lost them, and they simply never arrived.
After a month of waiting, that's when I put the rest of the keyboard together and figured I'd put the stabs in if they ever arrived. My family asked me "did you get a refund from the company?", and I just said "it's not really a company, it's just some dude in Taiwan, and it was UPS's fault...". I felt bad losing the money, but would also have felt bad taking the money back in case UPS eventually found it and sent it over. I should have been less timid, but oh well.
For six months, I used the Nearer with a 1.5u key as my spacebar and no stabs under Shift, Enter, etc. It worked perfectly fine, and I adapted very well to a 1.5u space, but it was embarrassing to look at and I knew I couldn't publish this article without proper stabs. So I ordered another set on ebay and they arrived about two weeks later.
With a 6.25u space.
I argued with the vendor over the course of nine!! emails that a 6u stab should be 95mm instead of 100mm, and he eventually sent a replacement.
On my previous, rubber dome keyboard, the stabilizer bars were fully accessible after simply removing the keycaps, so it didn't occur to me that Cherry stabilizers actually go underneath the plate, and are supposed to be installed before the switches are in place. But, I was able to add them retroactively, which I described in a video. This required cutting away some of my beautiful hot glue with a craft knife to make way for the bar.
If I had known these numbers before starting, I probably would have put the project off yet longer. But my technique of getting started before planning everything so I couldn't back down worked great.
Prices are expressed as $item+fees
in USD, since shipping / tax will be different everywhere.
item | price |
---|---|
140×Gateron Yellow | $29+18 |
129×keycaps | $40+9 |
150×1N4148 diodes | $12+1 |
Switchplate | $60+20 |
6u + 7×2u Stabilizers | $16+4 |
Elite-C controller | $18+5 |
USB-A to -C cable | $6 |
Odds and ends (hot glue) | a bit |
Coming in at around or just under $250.
And it would be wrong of me to ignore the benefit of materials I already had or borrowed from my family: Soldering iron, wire, hot glue gun, wood & woodworking tools, wood stain, sandpaper.
My mom kept asking me "are you going to make and sell these?", but with $250 material cost and at least 24 hours of labor, I don't think I'd find many takers.
Overall, I am satisfied. Typing on the Nearer feels cool, and I'm glad to have a unique piece of equipment that I put together myself.
Thank you for reading.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>By voussoir | April 24 2021 some time in the afternoon | 538 words | 505 spaces | 70 punctuation | 8 legs | 10 minute read for slow readers | 5 minute read for fast readers | 1 minute read for really fast readers | 0 minute read for readers who skip straight to the comments
Share this article on Facebook, Twitter, Reddit, Hacker News, TikTok, Tumblr, Vine, Instagram, Email, Medium, GitHub, The Pirate Bay, Steam Community, Bodybuilding.com, 4chan, Text message, OpenStreetMap, Thesaurus.com, StackExchange, YouTube, Facebook, Facebook, Facebook, Please I'm begging you to share it on Facebook
"What America needs today," said America's prime minister Mr. Minister McMinisterface," is more professionally written articles," he continued, in an interview last Thursday. "The kind with great," he went on, "big pull quotes and," he shared exclusively with a voussoir.net journalist who was also there on Thursday, "enough share buttons," he uttered with much conviction, "for our childrens'" he almost concluded on Thursday, "children", he concluded, overwhelmed with emotion.
This professional gentleman, to whom we now refer with a different pronoun so that we can catch search queries for "is Minister McMinisterface a professional gentleman?" (yes, Minister McMinisterface is a professional gentleman), says he feels very strongly about the issue.
But not everyone has the same opinion.
Some people have different opinions.
What America needs today is more professionally written articles. The kind with great big pull quotes and enough share buttons for our childrens' children.
The interview, which took place last Thursday and was held exclusively with voussoir.net reporters because our reporters are the best, took place last Thursday and involved much incoherent rambling with the occasional useful sound bite.
Mr. Governor, the governor of Governmentown said he felt differently.
I feel differently.
But voussoir.net's top journalists are not sure if he was responding to McMinisterface's remarks or simply commenting on the potency of the drugs he was smoking at the time.
The interview took place on Thursday after a long public debate earlier that Thursday between many members of the press regarding the quality of news and journalism in America.
Most news outlets don't use enough pull quotes.
McMinisterface and Mr. Governor were both involved in the debate, along with key executives from Fox, CNN, Disney, Comcast, YouTube, Little Debbie, the FCC, the Department of Defense, and the United States Air Force, whose involvement was initially unclear.
During the debate on Thursday, the prevailing opinion of those involved was that American media has room for improvement and there is nothing funny going on in Area 51 we'd like to make that perfectly clear.
It was noted that American media is still doing pretty well despite a few shortcomings.
Nothing funny going on in Area 51.
Among the shortcomings, McMinisterface said that most news outlets don't use enough pull quotes. He feels that pull quotes tell the reader the important bits so they can hurry up and get this whole reading thing over with. He repeated this sentiment to us during our exclusive interview on Thursday.
"The situation is not looking very good", remarked CNN staff on Thursday.
"We'd like to work more closely with advertisers," said YouTube's marketing department. "So far, sleeping with them hasn't proven to be close enough, and we're determined to get closer. It's all about making money. Can you erase that? I meant delighting the viewers".
Fox described American media's shortcomings as "everybody should be watching Fox why isn't everybody watching Fox just watch Fox", but was not willing to take part in the exclusive interview with voussoir.net journalists on Thursday because they were too busy watching Fox.
Little Debbie assured the public she would continue to produce baked goods and that there's nothing funny going on in Area 51.
The situation is [...] looking very good.
But our anonymous sources tell us otherwise.
Just before the end of the debate, the CEO of YouTube was awarded the world's first "Free Expression Award" after a unanimous decision by a committee consisting of just the CEO.
The rest of the interview was not very interesting so don't worry about it.
See also:
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>With Syncthing in one hand and Termux in the other, you can do almost all of your pc-phone file transfer wirelessly. Here's how to serve SSH and SFTP from Android.
I have an LG K10 running Android 7 with an SD card inserted. I find that Termux isn't able to write to the SD card. The GitHub issues say that you can write to one directory, but you can't get general access. You'll have to stick to writing to the internal storage.
Download and install Termux.
Run termux-setup-storage
, grant it permission, then reboot Termux. You can type exit
or pull down the notification and press the Exit button.
You will find a new folder ~/storage
which contains some symlinks to various directories on the phone. Personally, I prefer to remove this with rm -rf ~/storage
and then ln -s /storage/emulated/0 ~/internal
, but this is not required.
Run pkg install openssh
.
You will probably also want pkg install vim
.
At this point I am following the official Termux Wiki page on Remote Access, but I'll simplify the presentation:
Run cat /data/data/com.termux/files/usr/etc/ssh/sshd_config
to confirm that the contents match the default as seen on the wiki:
PrintMotd yes
PasswordAuthentication yes
Subsystem sftp /data/data/com.termux/files/usr/libexec/sftp-server
Run passwd
to pick a password. I'll be switching to key-based authentication in a minute so I'm just going to pick 1
as my password. Of course, this password doesn't apply to your whole phone, just the termux emulator.
Run sshd
to start the server.
You can run ifconfig
within Termux to find your phone's local IP address, or, depending on your home router, you might be able to assign the phone a hostname from the admin panel.
Open an SSH client on your PC. I'll be using Putty.
Enter the phone's hostname or IP address, and choose 8022 for the port, and start the session.
Putty may warn you that it has never seen the server's fingerprint before, which is expected and you can accept it.
In Putty, the server will prompt you for a username. You may type anything your want, or even leave it blank and just hit Enter. Then it will ask you for the password you chose earlier.
Congratulations! Try running a command like ls
.
Open an FTP client on your PC. I'll be using WinSCP.
Enter the phone's hostname/IP and port. When I typed 8022 into the port field, WinSCP automatically changed the protocol selection from SFTP to WebDAV, so change it back to SFTP. You may enter anything you want for the username, but if you leave it blank then WinSCP will prompt you during the login process, so maybe you'd like to make something up. Also enter your password, then log in.
Congratulations! Try uploading some files to the phone.
I assume you won't be leaving your phone's server on very long, or giving it an internet-facing port, so you can leave it in password auth mode if you want. But this is a great chance to get some practice with SSH keyfiles anyway, so keep reading.
When you downloaded Putty, you should have also gotten puttygen.exe
. Open that program.
Leave the key type as RSA and press the Generate button to make a public/private keypair. You can use the comment field to give it a memorable name.
You may give the keypair a password, but you'll have to type this password every time you log in with Putty/WinSCP, which you may not want to do. So you can leave it blank. In a 'real-life' SSH situation, you can use a passworded keyfile to double your security; someone would have to steal your keyfile and know your password to log into your servers.
Use the "Save public key" and "Save private key" buttons to write your keyfiles to disk. You can pick any kind of name and file extension you want. I use a name like voussoir.ssh.public
and voussoir.ssh.private
. Do not close puttygen yet.
We need to teach the server to trust the public key we've created. In Putty, use vim to create a file called ~/.ssh/authorized_keys
.
In the puttygen UI, the text box at the top has the text that needs to go into this file. You'll notice that the format of this text is <key type> <base64> <comment>
where the key type is ssh-rsa
, the base64 is the content of the publickey file you saved, and the comment is what you wrote earlier. To paste into vim over putty you may need to press Shift+Insert.
Save and quit with Esc + :wq
.
Also modify the sshd_config
file to disable password authentication. vim /data/data/com.termux/files/usr/etc/ssh/sshd_config
Close Putty and WinSCP. Stop the server with pkill sshd
and run it again with sshd
.
Open Putty again, and enter the hostname and port.
On the left menu, choose Connection > Data and put something in the username box so you won't get prompted during login.
Then choose Connection > SSH > Auth and browse for your private keyfile.
Before pressing the Open button, you may want to go back to the main Session screen and click the Save button to store the configuration. Then click Open.
Congratulations!
Open WinSCP again, and enter the hostname and port and select SFTP. Put something in the username box.
Click the Advanced button and select SSH > Authentication. Browse for your private keyfile.
You may want to save the session configuration. Then click Login.
Congratulations!
Now we'll put a shortcut on the homescreen to launch the server in a single tap.
Download and install Termux:Widget.
Using the shell or WinSCP, create the folder ~/.shortcuts
and create an .sh
file inside there. I'll call it sshd_widget.sh
.
Here is the content of my script file:
sshd
echo SSH server running.
echo press Enter to terminate.
read continue
pkill sshd
On your phone's homescreen, create a new shortcut widget from the Termux:Widget section. It will show you the files inside ~/.shortcuts
.
Congratulations!
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In September 1993, AOL brought Usenet access to the general public. Previously, Usenet was mainly available in institutions like universities, and saw waves of new users every September as freshmen got online.
New users have been coming online ever since, and that September never ended.
https://en.wikipedia.org/wiki/Eternal_September
https://voussoir.net/eternalseptember
Happy 10,000.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>On modern Android, applications can register multiple channels / categories through which they'll send notifications, so that you can configure different types of notifications to behave differently. It's a great concept, but the actual configuration UI leaves something to be desired.
Here's what it looks like to configure an app's notification channel:
For Medium and Low importance, notifications appear under a "Silent notifications" header on the dropdown:
And although the channel menu has an on/off switch for badges, there is a totally separate menu for choosing whether badges are numbers or just dots, because this option applies system-wide:
Similarly, if you want to disable status bar icons entirely, that's listed somewhere else:
And finally, there is another option that only applies to incoming phone calls that gives you ringing and vibration together.
So, if you want to modify all of the available options related to notifications, you'll have to make a Vernian journey through the operating system and hope you get it done in less than eighty days:
Notifications menu to enable status bar.
App & channel menu to enable the channel.
Channel importance submenu:
Level | Status bar icon | Dropdown area | Sound/vibrate | Pop up |
---|---|---|---|---|
Urgent | Yes | Primary | Yes | Yes |
High | Yes | Primary | Yes | No |
Medium | Yes | Silenced | No | No |
Low | No | Silenced | No | No |
Badge menu to choose numbers or dots.
Sound menu to choose phone call ring with vibrate, because phone calls are special.
Additionally, I think some properties are controlled by the app itself, such as whether to wake the screen or not. During my experiments with AnkiDroid, the synchronization notification never woke the screen even when the channel was set to Urgent.
My phone happens to be an LG, and their firmware has some bonus options that only apply to the lock screen, which is located in, you guessed it, a separate menu:
There are two main problems that afflict me every time I want to change something:
1. Mental translation steps: Before I even open the Settings, I've already decided what I want to achieve. For example, "keep this app's icon on the status bar, but disable its sound and vibration". The problem with Android's UI is I have to translate my goal into its terminology of importance levels, so that it can translate that back into the actual outcomes.
In my head, I'm thinking "keep icon, disable vibration", but on my screen I'm seeing "Urgent, High, Medium, Low". Well I don't want sound so I can rule out Urgent and High. Low... hmm, wait, is the status bar considered an interruption? I don't really think of it as an interruption. Not like the popups anyway. Oh, popups only apply to Urgent so I guess Low must disable the status bar. So that means I want Medium. Ok. That's a lot more work than "keep icon, disable vibration".
This wording is unnecessarily opinionated. I would say that having an icon on the status bar but no sound is quite low importance, but Android thinks that's a medium. The labeling sounds like it's catered towards people who have so many apps installed that they don't even know where their notifications are coming from, so to even appear on the status bar is a medium-level honor. And I would expect a notification marked as Urgent to ring many times so it's impossible to miss, because, well, it's urgent! But that's not the case. Why doesn't the UI just present me with facts instead of these subjective names? Then we could skip all this translation.
I'd also like you to notice that the wording switches from the affirmative voice, "Make sound", to the negative voice, "No sound". Instead of expressing their own outcomes, Medium and Low express how their outcomes contrast with Urgent and High, requiring me to cross-reference everything before deciding. None of the options even mention the status bar, it must be deduced from the contrast between "do pop up" and "no visual interruption".
And this is the simple case where the solution is entirely within the Importance menu. To configure incoming calls, or use LG's bonus settings, I have to figure out which menus I need to visit to satisfy each part of my request, and hit them up one by one.
2. Impossible combos: I'm starting to get confused with all these menus so maybe I'm missing something, but it seems to me that certain combinations of options are not possible through the UI. For example, to get popups I have to use Urgent, but this also implies sound/vibrate. What if I want an app's notifications to pop up silently, without setting my whole phone to silent because I still want texts to buzz? Some apps have this kind of choice built inside the app itself, which controls a parameter to its notification channel. And once again, I don't think lockscreen wake is an option exposed to the user, it seems to be the app's own choice.
As you saw, incoming phone calls have the option to ring and vibrate, but regular app notifications don't seem to have this option. With importance levels Urgent and High, I get a sound if my phone is in sound mode, or a buzz if my phone is in vibrate mode. From what I can tell, I can't get both. Maybe some manufacturers add this option to the firmware. But why is it like this?
Notifications either pop up, or don't. That's a binary choice. They make sound, or don't. They buzz or don't. Wake the screen or don't. All binary choices. Compare these two sample UIs:
Notification UI #1
No sound or vibrate, don't pop up
Vibrate only, don't pop up
Sound only, don't pop up
Sound and vibrate, don't pop up
No sound or vibrate, pop up
Vibrate only, pop up
Sound only, pop up
Sound and vibrate, pop up
Notification UI #2
Vibrate
Sound
Pop up
For these three behavioral options, UI #1 has 23 = 8 presented choices because each choice is packing a full three-bit state. UI #2 only needs the three checkboxes because they each represent 1 bit, a single binary choice. If you add in screen wake, UI #1 will have 24 = 16 options to pick from, while UI #2 will just have 4. Not to mention, #1 takes ages to read and understand.
With all of the different notification behaviors to control, you can imagine that 2n would quickly become an unnavigable mess. That's why the Importance menu lumps things together — the Urgent level enables popups, but also implies the use of sound.
Android's UI is a weird hybrid that uses style #1 for its Importance menu, with the lumping of behaviors to reduce the option count, but also uses style #2 for the badge, which is presented as a standalone on/off switch!
Orthogonality means you can change one thing without changing anything else. The badge switch is on or off, and doesn't affect any other behaviors. It gets an orthogonal seal of approval and a handshake from the governor of Orthogon. The Importance menu has certain behaviors implying others, and makes some combinations of behaviors impossible. It gets a disappointed frown.
To me, it is clear that the UI should make much, much heavier use of checkboxes / toggle switches:
Notification Channel
Enabled
Vibrate
Sound
Status bar
Popup
Badge:
No badge
Dot badge
Number badge
Wake screen
Blink LED
LG Bubble
LG Sidelight
et cetera
Some notes:
Now, you'd probably want to have a page for configuring the default settings to apply to new and unconfigured apps. Then, perhaps, each of these checkboxes would be replaced with a choice of explicit yes, explicit no, and follow default. The UI should also remind you what your default is set to, so you don't have to cross-reference it.
And that's it. All you need is one menu for setting the default configuration, and one menu for configuring real channels. No more of this scatterbrained, ten screens of goose chase UI. Just let me control my device!
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>According to Google Trends, the term cancel culture started to appear in late 2019 and had its big heyday in mid-2020, so in internet years I'm rather late. I think the concept of cancel culture is plain stupid: a bunch of people who have willingly centralized themselves under a privately-owned social media site whose primary / only source of revenue is advertisements act surprised and indignant when they're kicked out because they're harming the company's image.
For the past couple of months, every time I've seen an article about cancel culture or someone getting "cancelled", I've gotten a spur of inspiration to write something about it, but I've always decided against it because my conclusion is just so trivial. Stupid games. Stupid prizes. That's about it. Maybe someday people will learn to stop investing their lives into social media giants. Right after they learn that fire is hot.
But, with the recent suspension of Donald Trump's Twitter account, I'm going ahead and posting this one because maybe he'll read it and I can help enact some real change around here.
Did you know?
You can make your own website, and you can say whatever you want there!
It's true! Just head on over to w-w-w-dot-icann-dot-org to learn all about how owning your own domain works, and watch this helpful guide to learn how to navigate the internet.
Let's use an analogy: if you go inside someone else's house, and say something they don't like, they can kick you out. You might think their rules are totally lame, and may even be cramping your style, harshing your vibe, or throwing off your groove! But that's the way it goes when you're in someone else's pad, man. It's okay though, because when you go back to your own house, you can do anything you want. You can even listen to Nickelback. The same is true on the internet. Go make your own website and you won't have to consult anyone regarding what you post.
If, by chance, your web host does decide to stop hosting your pages, all you have to do is pick a different one and restore from a backup, because of course you're making regular backups of the things you care about and not just expecting the internet to keep everything for you forever. With the standardization of web protocols, every web host is functionally the same! It's totally commoditized, dudes!
For the videographically inclined among you, I'm sure you're thinking "But how would I ever host my videos without Youtube? I can't afford to do it myself!". Congratulations on discovering that hosting and distributing video is stinking expensive! People don't seem to have any trouble understanding that mansions are expensive, and that getting kicked out of one doesn't automatically grant you access to another. Sorry you got comfortable.
Did you know?
Your readers can use RSS to see when you make a post, without all the hassle and fuss of intermediaries!
Let's talk supply chains. Every supply chain manager knows that you want to keep the number of middle men low, because middle men always find a way to take their cut. If the words "chronological newsfeed" ring any painful bells for you, you already know what kinds of cuts these middle men take, and that's just the beginning.
Luckily, Mr. Berners-Lee did a real bang-up job on the whole web thing. He made it so you can send information directly between yourself and another person. What a cool guy. And when you use encryption, you can be sure the signal comes through loud and clear even as it passes through your ISP's lines. You know how much I love these standardized protocols. Just set up your RSS feed, and your readers can interact with it however they'd like! The opportunity for self-sufficiency is right under your nose!
You might find that building an audience around your own domain is quite difficult. Weaning off the teats of the internet megaphones and their algorithms can take some time, and you might feel the urge to go crawling back. But it's live by the tweet die by the tweet over there. You want longevity and independence, you put in the extra work. That is, if you believe that what you publish is worth anything.
Did you know?
Putting all your eggs in one basket has been considered bad practice ever since eggs were invented! Or was it the chicken...
Stop by any local accounting office and they'll all tell you the same thing: diversify! diversify! diversify! Here on the internet we love to think we're pioneering new things at every corner, but in fact the concept of risk management is very old! If you're relying on a single party with whom you have no real contract to maintain your entire internet presence on an account you got for the low price of $0.00, you're just asking for trouble! I don't know why this is so hard for you!
The difference is that the baskets of today are different from the baskets of a hundred years ago. You know they just don't make 'em like they used to. See, these baskets have a real vested interest in getting you to put all your eggs there. They'll tempt you like the devil himself, promising likes, followers, and views. You've got to resist. Just do what I do, and write articles that nobody ever sees.
It's okay to have a Twitter account, and a Youtube account, and a reddit account. Some may even say it's okay to have a Facebook account! But if you don't have a contingency plan for when you lose that account, for a good reason or bad, you're simply not prepared!
None of this is to say that if a platform does something you disagree with, you should never speak up. You can let them know that you think what they did is wrong. Just remember that your right to free speech doesn't trump their right to ignore you! Social media didn't come down to us from on high, it's made by people and they can do what they want.
Donald, you're in a great position to help both of us out here. Start telling people about the decentralized web, independent publishing, Net Neutrality, and RSS, and you'll be doing the internet a favor the likes of which we haven't seen in years. You're always making a show of your dissatisfaction towards mainstream publishing, so this should be right up your alley! We get renewed interest in open protocols, and you get a place to put any old thing you want with nobody to stop you! It's a win-win!
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Oh. My. God. Systers. Listen up. See that database in that corner there with the cute leather-bound journal? Don't stare! Yeah, that's SQLite. SQLite! You know!! Well, he's oooonly the handsomest, hunkiest piece of OSS in pretty much the whole world.
SQLite's got, like, billions and billions of installs. I mean there's basically more SQLite installs than people. I bet you've got a dozen in your purse right now and you don't even realize it, that's how installed he is. And he hardly even flaunts it. He's written in C, right, so he's like the most cross-platform thing you've ever seen besides blinking LEDs.
Girls, we gotta talk testing. You know how most libraries just moan and whine awwwwww, do I have to? do I have to do testing? I don't waaaannaaa and they just ship without it, right? Such babies. What a turn off. It's just so typical. I mean, like, you only spent hundreds of hours on that program, surely you don't wanna make sure it actually works, do you? Then oops! it's full of bugs! Like duh!! Or — or — they'll import the latest hotshot testing library they saw on Twitter and pack it to the lid with mocks faker than their designer jeans and fixtures that wouldn't even fit in their SF studio apartment. Is that what passes for testing these days? Talk about posers. Then there's SQLite and, just listen to this: "The reliability and robustness of SQLite is achieved in part by thorough and careful testing". Understatement. of. the. YEAR! SQLite's got six-hundred-and-forty times more test code than actual library code. No! I'm not joking! And these are honest-to-god full branch coverage tests we're talking here. SQLite's got more tests than you've got self-respect and then he's got self-respect on top of that.
Okay, now see that other repository by the bar? The one who's always posting selfies on Medium and Show HN? Yeah, he's got like three monthly pageviews and ten GitHub stars total and still has the gall to license himself under a restrictive license. Pffffft! yeah!! right!!! As if anyone's gonna wanna steal that. Gross!! Get real. Meanwhile SQLite is literally in the public domain. Not even the Linux kernel is willing to go there. God that's so hardcore. Can you believe it? SQLite's like "you wanna copy me? sure thing". Go ahead and find one other piece of software with THAT much confidence. I'll be waiting. So don't waste my time telling me about your dates with ""humanitarians"" because the most devoted, generous, and well-indexed humanitarian I've ever seen is sitting right. over. there.
He's not the kind of open source that says "if you found a problem, just make a pull request". No way. If you do that, SQLite literally won't even use it. He'll rewrite the whole thing from scratch without breaking a sweat. Well, because it's the right thing to do! To maintain the purity of the public domain and everything. You can scrape Stack Overflow alllllll you like and you won't find a single line that's been copied into the SQLite source. That's for children, and children don't know how to run a business with projections to 2050 the way SQLite does.
And the docs. Wow the docs. I'll text you the link later, you've got to check them out. Not only are the docs backed by an SQLite instance on a shared VM with twenty-three others that STILL maintains a system load below 0.1 — because SQLite is a gentleman and that's what gentlemen do — but the tone throughout the whole thing is just dripping with confidence but, like, also humility. Is that an oxymoron or something? Who cares. Like there's a whole section telling you when NOT to use SQLite and, turns out, SQLite is still pretty much always awesome. Not like those desperate, insecure modules that gotta sound like they're made of pixie unicorn dust just to get your attention. Or even worse is when they're backed by a proprietary web service. Um, no thanks! Don't you know you're competing with an in-process database here? You can literally even download the support forum to read through it offline, that's how independent SQLite is. And just check the page source when you're reading the docs. First time I did I was like "whaaaat! where's all the javascript!! isn't this the modern web!!" you know what I mean? No way. SQLite's old school. I bet he gets his B-Trees properly tailored and everything. Mmmm, how I'd like to see that! So lean but still sooo powerful. What a hunk. Oh and those properly SVGed railroad graphs, the ones that even work with ctrl+f? Now those have saved my bacon more times I'd care to admit. Speaking of old school, take a look at the comments inside the amalgamation sometime. I mean of course they're exemplary, but notice anything about the punctuation? Wow, what a throwback.
Now, it's been a long time since one-liners were in fashion. I mean it's so eighties. Like leg warmers. Most of the time, I hear a one-liner, and I'm like, come on Schwarzenegger stop it already. But SQLite just pulls it off somehow. "Small. Fast. Reliable. Choose any three." Now THAT'S a timeless line. If every program was even 5% of what SQLite is, the world'd be a better place. Oh! Shhh! He's coming this way!
swoon, faint
SQLite makes me feel inadequate.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>On Windows, the file extension of a filename is used to automatically determine how the file should be opened when you double-click on it or run it on the command line. .exe are the kings, because they are Windows's native executables. For other extensions, the shell checks the registry to find the exe associated with the extension, and runs that program with your file as the first argument, plus the rest of your arguments. For example:
> ipconfig.exe
→ runs directly> whatsmyip.py
→ python.exe whatsmyip.py
> dns.py www.example.com
→ python.exe dns.py www.example.com
> clock.pyw
→ pythonw.exe clock.pyw
> report.doc
→ winword.exe report.doc
If you remove the .exe extension from an executable file's name, the shell won't know what to do with it (but deeper APIs can still invoke it (one, two)). That is to say, Windows does not inspect the content of files to determine their type for the purpose of double-click launching. Every file is either an exe or has an extension which maps to an exe, or has no extension and can't be associated to a program. [1]
At no time does this prevent you from using any other executable to open a file. You can always pythonw.exe dns.py
or winword.exe clock.pyw
. Extensions are not restrictions, they are just shortcuts to launching your executable of choice.
[1] There is also .com, a legacy executable format which is natively executable, yet has a passthrough HKCR entry anyway, presumably because the shell is programmed to consult HKCR for anything that's not .exe. HKCR\comfile\shell\open\command\(Default)="%1" %*
On Unix operating systems, the extension is not used to help execute the file. Instead,
x
permission, aka "executable bit", enabled by chmod +x filename
.The shebang is a line which must be at the very top of the file and must start with #!
. Then, a path to an executable is given, which will actually interpret and run the remainder of the file. A Python file with a shebang might look like this:
#!/usr/bin/env python
import sys
print(sys.executable, sys.argv)
You can save this file using any extension you want, or no extension at all, and run it by calling chmod +x ./filename
and then ./filename
. As always, you're welcome to pass the file as an argument to any other executable if you need to use a different interpreter.
One of the principles here is that executables become abstractions, black boxes. The idea is that as a user, when you run some program
on the command line, you shouldn't need to know or care whether program
is a shell builtin, or an alias, or an executable on the PATH; and you shouldn't need to care what language it's written in. You could swap out a dns
program written in bash with one written in Python, and your callers won't know the difference.
But...
And you won't find a shebang on any of the code I write.
For these arguments, suppose that the file in question is checked into version control (e.g. git), or is seeding on IPFS, or is otherwise being hash-validated, or is restored to factory condition on every software/OS update, such that "just change the shebang" is not an appropriate solution. The file is handcuffed to the interpreter specified by the shebang.
My dislike for shebangs is part principle and part practical. Principles like:
As a user, why should I be expected to agree with the developer's choice of interpreter and pathing (/bin/x
vs /usr/bin/x
vs /usr/bin/env x
...)? You can search stackoverflow and find plenty of discussions about the pros and cons of each technique. But I'm the user and I'll do what I want, stop subjecting me to your chosen set of pros and cons when I'm the one running the program.
As a developer, why should I add this boilerplate to every file I write? Why should I be encoding "this is how you run my program" in the file, when the user can simply configure their system to do it however they like best?
And practicals like:
My python
is really not the same as your python
, so stop assuming /usr/bin/env python
is the right thing.
The shebang handcuffs also apply to hardlinks / symlinks which I might intentionally want to behave differently.
I will continue to use Python as the example language for this argument because that's what I'm most familiar with, but you may extend these issues to any case where there are alternative interpreters — even if the alternatives haven't been invented yet!
Back in the day, Python code was written in Python 2, and it was fair to assume that the executable named python
on the PATH was the Python 2 interpreter, so people wrote shebangs pointing to python
expecting P2. Now, code is written in Python 3 and systems are shipping with python
referring to P3, but some P2 tools are still around and in use. So now their shebang is wrong, and will be wrong for the rest of time, and the user will always need to explicitly call python2 program.py
for as long as they hang on to that file. Great, thanks.
On an extension-based system, the solution is easy. Although the program.py
file might be checked into version control, there's nothing stopping me from creating a symlink or hardlink on my PATH called program.py2
that points to the file, and an extension mapping from .py2
to python2.exe
. This requires no changes to the file content itself, so it won't interfere with the file's hash.
To be clear, the file layout I would use for maintaining a Python2 and Python3 program simultaneously is:
D:\
├───cmd\ on the PATH
│ ├───a_program.py2 => D:\software\a_program\a_program.py
│ └───b_program.py => D:\software\b_program\b_program.py
└───software\
├───a_program\
│ └───a_program.py
└───b_program\
└───b_program.py
So even if a_program.py
was written when .py
implied Python2 instead of Python3, it doesn't matter because the names I actually execute are those in \cmd on my PATH. I can name my links any way I want to take advantage of the file extension mapping, while the real software is not affected whatsoever. See Master of my domain for more about my software management practices.
Sure, you can say that nobody should be using P2 programs any more, but that's moving the goalposts. Let's say someone wants to run some particular set of Python scripts through PyPy or any other implementation. What then? To give one non-Python example, here is an SO thread about the right shebang for bash. To my eyes it's a disaster:
/bin/sh
under the assumption that all people have that symlinked to bash, which is wrong./bin/bash
or /usr/bin/bash
might be ok, but there's no guarantee that's the path for bash
./usr/bin/env bash
is probably most common, but there's still no guarantee that's the path for env
!On a shebang-based system, the choices are:
/usr/bin/python
so I create a symlink /usr/bin/python => /.../python3
I don't like shebangs, but it's not such a big deal — all I have to do is not use them and that's that. They pose no restrictions upon me as long as I call the interpreter myself.
What actually bothers me are the Unix elitists who in a single breath will mock Windows users as being stupid, helpless lusers, pushed around by the Big Bad File Extension Who Dictates How Files Are Executed... then write a shebang that handcuffs their file to the name of the anticipated interpreter executable. A .rose by any other extension would smell as sweet.
To demonstrate this isn't a strawman, here are some actual quotes gathered from around the 'net:
I know that files are identified by an identifier on their first line, which is why Linux files don't have file endings. But I liked file endings a lot. Isn't it nice to be able to tell what a file is/does without having to open it? In Windows I could open up a folder and immediately have a lot of information about the folder and the files within it, just from the file endings.
If you're asking if there's some kind of setting that will "show" file extensions on system files, no, that is not a thing. You seem really hung up on the idea that filename extensions are a superior method of associating type information with files. Most Linux applications just don't use this method, but have other ways of determining that information. Your question is based on the assumption that this is some kind of feature which has been disabled and can be re-enabled, which is fundamentally untrue.
I will not: I will not allow the ignorance that spews from Redmond to infect my software.
I will not: I will not cater to users with a broken OS.
I will not: I will not bother because it represents the minimal technical hurdle for Windows users.
[A developer renames his
readme
toreadme.txt
]While it may make logical sense to some people, the ultimate implication when you see a .txt file is that the developer uses Windows. I'm not sure a lot of developers are comfortable with that.
No. File extensions are stupid and broken.
Why? What's wrong with encoding metadata about the content in the filename?
Because it then prevents me from changing the filename the way I want to. Because legacy garbage.
Interesting... most commenters here (so far) seem to be against the extension. Can someone explain why? "README" doesn't tell me if it's text, or markdown, or HTML, or anything. Having ".txt" lets me know the format without opening it first to see.
I hate them because they're an abstraction leak. The type of a file's content is different from the application that I want to use to manipulate it, which both are in turn different from the name I chose to give the file. That current file systems and the GUI representations on top of them are so badly designed as to confuse three unrelated concepts is a failing of software and as clear an indication as you could ask for of the triumph of Worse Is Better.
These two in particular point out a problem that's already solved on Windows:
You should not use an extension for executables, as they they are not interchangeable. Imagine that you have a shell script a.sh, then re-write in python a.py, you now have to change every program that calls your script, you have leaked an implementation detail.
If you give a shell script a .sh extension, you'll have to type that .sh as part of the command name when starting it. That's the main reason why I don't like putting that extension in.
We need to talk about PATHEXT.
On Windows, there is an environment variable called PATHEXT. It contains a semicolon-separated list of file extensions that you don't have to type when running programs on the command line. For example, if .py is on PATHEXT, then you can just ask for dns
on the commandline and dns.py
will be a valid candidate. On the other hand, if PATHEXT is blank, then you must type the file extension for every executable, even .exe. At that point, the shell builtins will be the only extensionless commands you can run.
The order of extensions on PATHEXT indicates the order of preference for candidate files.
C:\anywhere>set PATH=C:\cmd;C:\Windows\System32
C:\anywhere>set PATHEXT=.py;.bat;.exe
C:\anywhere>where dns
C:\cmd\dns.bat
C:\cmd\dns.exe
C:\cmd\dns.py
C:\anywhere>dns
You ran dns.py!
C:\anywhere>set PATHEXT=.bat;.py;.exe
C:\anywhere>dns
You ran dns.bat!
C:\anywhere>set PATHEXT=.exe;.bat;.py
C:\anywhere>dns
You ran dns.exe!
C:\anywhere>set PATHEXT=.py
C:\anywhere>where.exe dns
C:\cmd\dns.py
C:\anywhere>where.exe dns.bat
C:\cmd\dns.bat
C:\anywhere>dns
You ran dns.py!
Notice I am now calling where.exe
, since .exe is no longer on PATHEXT, thus where
no longer matches C:\Windows\System32\where.exe
.
C:\anywhere>set PATHEXT=
C:\anywhere>where.exe dns
INFO: Could not find files for the given pattern(s).
C:\anywhere>where.exe dns.py
C:\cmd\dns.py
C:\anywhere>dns.py
You ran dns.py!
Regardless of the value of PATHEXT, you are always allowed to specify the full name of the file, like dns.py
. Even if .py
is not on PATHEXT, dns.py
itself is still on the PATH. PATHEXT only affects the evaluation of the bare name, dns
.
And just like that, we've achieved the black box principle of executables. You can rewrite a .bat program in .py, or you can supercede a System32 exe with a script of your own. The only thing you can't do is supercede the shell builtins — dir
always does dir
even if you have a candidate in the cwd or on the PATH — you'll have to call those files by their extensioned names.
Between my public cmd repository and my non-public cmd folder, I've got more than 180 .py and .bat files making up my command line toolkit. Of course I'm not specifying the extensions when I run them, guys.
It's time for me to bat for the other team and explain why Windows's solution is also bad.
The Windows registry is not a beautiful place, and the mapping of extensions to executables is not as easy as one would hope. With Windows 10, Microsoft has introduced some new APIs for dealing with extension associations, mostly because with the old APIs, inconsiderate software developers would non-optionally dive into the registry and set their program as the default for a bunch of filetypes during install, leaving the average user without a clear understanding of how to revert. However, I haven't learned these new systems because Windows refers to them as "default apps" and I have a vendetta against the word "app" so I avoid that whole interface at all costs. When I need to edit extensions, I always just open the registry and do it myself.
The most straightforward technique that I'm familiar with is to create a key HKEY_CLASSES_ROOT\.ext
. You can give it a (Default)
value containing the name of another HKCR key, and this will act as a redirect for the remainder of the process. Then, beneath either the .ext
or the redirect destination, you create shell\open\command\(Default)="C:\myprogram.exe" "%L" %*
for the most simple invocation.
Beyond that, it's all a little confusing with keys like OpenWithList, OpenWithProgids, and values like Content Type and PerceivedType (do they do anything for files without an explicit shell\open\command
?), and if you want to make two extensions that run the same program but have different icons (.txt, .srt, .css → text editor) you wind up duplicating the whole shell command for each of them because you can't do multiple-inheritance style mappings. Unless I'm missing something, which is also likely.
Also, there are even more keys in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ext\UserChoice
. When dealing with extensions that I didn't make myself, NirSoft's filetypesman helps me locate their hodgepodge of keys.
The point is that while I prefer extension-executable systems over shebang systems, that does not mean I'm praising the registry as it exists today.
A common criticism of Windows is that non-savvy users can be tricked into downloading some file called "Hotel California.mp3.exe" and running it because they think it's an mp3 file. This is made 1,000 times worse by the unfathomable, unforgiveable, bone-headed decision by Microsoft to hide file extensions of "known file types" by default, hiding the .exe
but leaving the .mp3
. It boggles the mind and stupefies the senses that this default is still in place after all these years, but it is.
On Unix, the downloaded file would not be executable until you chmod +x
, which is something you can't trick most people into doing. On Windows, the .exe requires no activation and is ready to detonate as soon as you double-click on it.
That's why UAC was added to Windows, but users will Accept any dialog box that stands between them and their mp3 without reading it, so that hasn't changed much.
Let me re-quote two of the comments I shared above:
Because it then prevents me from changing the filename the way I want to.
The type of a file's content is different from the application that I want to use to manipulate it, which both are in turn different from the name I chose to give the file
These comments make a good point, that it would be nice to have the ability to associate files to programs without having to name them a certain way. Computing is still a relatively young field, and I wouldn't mind seeing new ways of solving this problem. I mentioned that I'd like to see some multiple-inheritance, which would simplify icon management, default programs, and human-friendly type names. But, by my insistence on maintaining file hashes, you can infer that I'd like a solution out-of-band from the file content itself. Current implementations of alternate data streams are not ready to steal this stage because they aren't transmitted when sharing the file over the internet, for better and worse.
For now, I am satisfied with file extensions (as long as I wrangle the registry myself), and I want the Unix elitists to see how I use them in my favor; that they impose no friction on my workflow at all. inb4 Stockholm syndrome.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>This article is about how I manage the software on my computer to stay organized and in control. I've developed these habits over years of dealing with software installations that each want to behave a little differently and go their own way. But I'm the master of my domain — queen of my castle, if you will — and I run the show around here. So here's how I put software in its place:
If a software download page offers a choice between "portable"/.zip/.7z downloads and "setup"/.exe/.msi downloads, always pick the portable option. The reason they're called portable is because you can unzip them to a flash drive and just run the .exe on any computer you plug it in to, so that you don't have to actually install the program on every computer you use.
As a result, a well-behaved portable program will:
These properties are what I want from all software! The benefits even for non-portable use are many. Portable software makes it easy to:
There is even a website, portableapps.com, dedicated to promoting portable software and preparing portable-ized versions of software that isn't normally available as portable. In the second case, however, you rely on portableapps being trustworthy.
Ostensibly, the benefits of installers over portables is they can set file associations, integrate with the right-click menu, and so forth. Well, I can handle file associations myself (HKCR\.ext\shell\open\command\(Default)
), and even the most well-meaning context menu items really just contribute to an ever-growing list of junk so I'd rather not have those anyway. I can write those myself, too, if I really need them (HKCR\.ext\shell\mycommandname\command\(Default)
). Then I'll know exactly where they're defined should I ever decide to remove them. This is in contrast to properties set by installers which are always in crazy places and mapped through GUIDs and whatnot.
Some software isn't available as a portable download, so you've got to suffer through the installer. If it gives you the opportunity to change the install directory, always take that chance. Software installers on Windows have a nasty habit of scattering themselves throughout C:\Program Files
, C:\Program Files (x86)
, C:\ProgramData
, and %appdata%
. I'm king of this county and I hereby declare that I'm not gonna go on a wild goose chase looking for my software on my computer — they'll go where I tell them to go.
If I have to install a program from an installer, I'll usually try to zip up the resulting folder and keep that as my own portable copy for later. A lot of installers are nothing more than extractors, so as long as the program doesn't rely on some system changes during install, keeping the portable copy works fine (besides, system changes are often anti-user anyway). And I really don't need an installer acting as a glorified file extractor, I can do that myself from a zip. Unfortunately, some software doesn't work after re-extracting it, and I do have to keep the installer.
Some software authors take this Lèse-majesté a step further by not even offering a chance to change the install directory. There is no justifiable reason for this. I operate on a two or three strikes policy depending on how important the software is: I expect simply moving the installed folder, possibly leaving a junction in its place, to work properly. But now that the program is on my bad side it takes a lot less for me to uninstall.
The worst offenders are the likes of Adobe. A search on my computer right now shows:
C:\Program Files\Adobe
C:\Program Files\Common Files\Adobe
C:\Program Files (x86)\Adobe
C:\Program Files (x86)\Common Files\Adobe
C:\ProgramData\Adobe
C:\Users\All Users\Adobe
C:\Users\voussoir\AppData\Local\Adobe
C:\Users\voussoir\AppData\LocalLow\Adobe
C:\Users\voussoir\AppData\Roaming\Adobe
C:\Users\voussoir\AppData\Roaming\Adobe\Adobe
C:\Users\voussoir\Documents\Adobe
C:\Users\Public\Documents\Adobe
You're not the lord of this manor, Adobe!
My Software folder looks like this, with a subdirectory for each version of every program:
D:\Software\Git\2.25.0
D:\Software\Inkscape\0.92.3
D:\Software\QuiteRSS\0.19.4
D:\Software\WinSCP\5.17.8
This way, I can maintain multiple versions of the software at the same time, which makes updating totally stress-free because I can stick with the old version as long as I want if the update has a regression. Contrast that with an in-place updater where you might regret the update after finding a new bug. My Android phone has several apps that I simply don't bother to update because I don't want to deal with reverting the .apks by hand through adb should I regret the update [1].
The only problem occurs when multiple versions expect %appdata%\Program
to belong to themselves alone. If there is no commandline switch to change the appdata directory, I am somewhat out of luck on that point. One thing I had never though of until now is modifying the environment variables before running the program to manipulate %appdata%
to a separate directory, similar to this SE thread. However, that solution didn't work for me, but I'll keep an eye out for something similar. This seems fragile since the program might (wrongfully) construct appdata from %userprofile%\appdata\roaming
, or cache the value of %appdata%
during install to a registry key, etc.
[1] F-Droid offers historical apks for download so I've got no concern there, but Google doesn't. Raccoon can help you download present-day apks from Google for your future benefit, though.
Here's a fantastic trick I started using just recently. Since all my software is separated by version number, when I download the newest version of a program, all of my shortcuts or scripts which call that program will still be using the old path, and I'd have to update them manually. I came up with this solution: just mklink /j __latest X.Y.Z
inside the program folder, and have all your shortcuts point to the exe inside __latest
. Since it's a filesystem junction, it will behave transparently to any calling program. In the past I had tried to achieve this by making a single shorcut and pointing any future shortcuts to that one, but that didn't work because when you assign a shortcut to a shortcut it resolves to the real path and saves that path forever instead of folowing the link every time.
When I download a new version of a program, I just delete that junction and make it again with the new version number, and all linked paths work as normal, as long as the name of the .exe itself hasn't changed.
I don't like filling up my desktop or start menu with shortcuts, so I wrote PGUI which acts as a launcher for any .lnk files located inside my PGUI folder. Each of these shortcuts actually point to the __latest\program.exe
path. As a bonus, my PGUI folder is one of the few folders to enjoy the honor of being on my PATH, which means I can just start them from the command line or Win+R — that's all possible without a gui launcher of course, but it's a great symbiosis.
The entire contents of my PATH are:
C:\Windows
C:\Windows\system32
D:\cmd
D:\git\cmd
D:\git\cmd\PGUI
Two folders for system executables, and three folders owned by me, because this is a monarchy and I'll appoint whoever I want. No application, under any circumstance, gets to put its own install directory on the PATH. If I need global commandline access to that program, I'll put an .lnk or symlink in \cmd.
At one point, I had some issues with programs that I wanted to subprocess from Python. subprocess.run(shutil.which('ffmpeg'))
was breaking because subprocess.run
wants to receive executable files and of course the only thing on my path was an .lnk. So, I wrote winwhich.py and now that problem is solved. The software bends to my will, not the other way around.
I've mentioned that even portable software has a tendency to leave a few traces in %appdata%
. Sometimes it's inconsequential stuff like log files, but sometimes it's config, and that I want to keep in the program folder.
The solution here is in three steps:
%appdata%\Program
into D:\Software\Program
.mklink /j "%appdata%\Program" appdata
.Now you are closer to portable enlightenment and can zip up the program folder without losing your appdata files.
Although I run regular backups, I don't include my whole Software folder in the backup routine because I already keep all the portable zips and installers backed up separately. The only items of value in the install directory are config files, most of which are not highly personalized and I don't mind losing either.
But, there are a few programs which I've heavily configured and I'd hate to start from scratch with them. Sublime, Putty, and WinSCP for example. For those I wrote a wrapper around WinRAR, rarpar.py, which I use to create highly compressed archives with a datestamp in the filename. Because the __latest
files will be included in duplicate, you might think it'd waste a lot of space, but with a Solid archive and a very high dictionary size, that duplication causes no extra disk usage.
If you find that one of your programs isn't cooperating with the above techniques, consider these more delicate approaches:
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>The RSS URL for a multireddit is https://www.reddit.com/user/username/m/multiname/new.rss
. But, putting this into your RSS client without making the multi public will yield a 404.
On reddit.com/prefs/feeds you'll find some RSS links that use a static token in the URL to act as the authentication, so you don't have to provide login credentials in your client. It turns out, the token is the same for all of the feeds, and you can use it on the multireddit feed too.
Just use https://www.reddit.com/user/username/m/multiname/new.rss?feed=XXXXXXX&user=username
and you're good to go.
Since a single multireddit can aggregate up to 100 subreddits, you can save yourself and reddit up to 99 web requests per refresh by doing it this way.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Over the past year or two, more and more podcasts have been moving to Spotify and pulling their material from their other outlets. This is because Spotify wants to pump up their subscriber counts and is offering cash incentives to podcasters for exclusivity. The only situation in which this can possibly be interpreted as a benefit for the listener is when the exclusivity deal literally saves the podcast from going bust, and even this has caveats. Any other messaging that depicts Spotify-exclusivity in a positive light is pure spin and marketing, as the deal invariably removes control and choice from the listener. You can ignore the "oh, but Spotify's not that bad" crowd, because that's not the point. The point is that being corralled into Spotify is bad, and the same would apply to any other exclusive distribution point no matter how technically good it is.
Not to mention, as with any other material on the Internet, every day that passes is a day your favorite show might disappear for any number of reasons. You should also download your favorite Youtube videos and forum threads, too, but let's save that for another article.
Podcasts are often distributed as 128 kbps mp3 or thereabouts. At this bitrate, you can fit 100 hours of audio in 5.5 GiB. Just do it.
I am actually a bad ambassador for this kind of thing, because I like writing my own scrapers and downloaders, which most people won't want to do.
Let's start here: the podcast culture has traditionally used RSS for publishing episodes. Until recently, I never had a use for RSS, but now I see it as an important open format in the fight to keep data out of walled gardens like Spotify.
At this point, you can either search the Internet for "RSS podcast downloader" and find a pre-existing software solution to this problem, or you can continue reading and see how I do it. As you'll find, the nature of RSS does often require getting dirty and putting in some extra labor.
With no background experience in RSS readers, I tried QuiteRSS and have been happy with it. QuiteRSS uses SQLite to store the feeds and news items. With a tool like sqlitebrowser, or just the command line sqlite3, it's then trivial to get the published
date and enclosure_url
fields which I then throw into my own threaded_dl.py
by preparing a file that looks like:
https://example.com/episode1.mp3 Podcastname 2015-10-31.mp3
https://example.com/episode2.mp3 Podcastname 2016-12-25.mp3
https://example.com/episode3.mp3 Podcastname 2017-04-01.mp3
https://example.com/episode4.mp3 Podcastname 2018-05-05.mp3
and calling threaded_dl links.txt 3
.
To be clear, I only do this for the initial download of the historical posts. After that, when new episodes are released, I just right-click & save file.
However, you'll find that many or most RSS feeds don't contain the entire history of the show. Squarespace, for example, only publishes the 300 most recent items in an RSS feed. Why? Because that's the number Apple uses and apparently it's easier to follow Apple's lead than to realize that RSS is an open format for a variety of consumers. I have seen other feeds that show only 10 items, which surely must be a result of poor configuration [1].
One thing you can try is searching the Wayback machine for the RSS url. If you're lucky, it will have been scraped in the past often enough so as to contain the entire history, though perhaps in piecemeal. You could download the snapshots, combine them into a single xml file, serve it out of a webserver, and temporarily point your RSS client at localhost so it ingests all those historical posts before pointing it back at the real url. Convoluted, perhaps, but I'd rather do this than inject the posts into the db myself. Then, you can pull the enclosures out of QuiteRSS's database (or from the xml file you just made).
But, in the worst case scenario, you'll find that Wayback doesn't have archives of the feed you want. At this point I write a web scraper in Python to find all the episode dates and links, or I just hit the CTRL+C, CTRL+V gym for twenty minutes, copying each link from the website manually. You may also try Xenu's Link Sleuth or HTTrack to see if they can find all of the MP3 urls automatically. I figure it's an effort I'll only have to do once as long as RSS keeps getting new posts after that.
If the podcaster has already taken the Faustian bargain, you can try using spotifeed.timdorr.com to pull Spotify as RSS, but this will give very limited history and only serves to stem the bleeding.
[1] Looks like the market has an opening for an "RSS rebroadcasting service" that archives feeds and gives clients the whole history every time.
Some podcasters add metadata to their distribution files, others don't. Most don't. At least not to my tastes. I recommend MP3Tag for tagging and renaming the files.
Tagging podcasts is a little different than tagging music. Firstly, podcasters sometimes release "bonus episodes" or "0.5" episodes, which cause track numbers to deviate from the episode number as listed in the title. Secondly, music files can usually be named artist - album - track.mp3
without much issue, but podcast titles are often much longer and contain unsafe characters like :
, ?
, /
, etc. So, to keep things simple, I just use podcastname - releasedate.mp3
as the filename.
If the mp3 files don't have the ALBUM
or YEAR
field set, you can use MP3Tag's "filename to tag" feature to fix that.
MP3Tag is great for batch renaming. In your MP3Tag actions, create a Format value
action with the parameters Field=_FILENAME
, Format string=%album% - %year%
.
Clean up all the files' tags to your heart's content, then select them and run your rename action.
I don't listen to ads. I recommend mp3DirectCut for cutting them out. If you're going to listen to the podcasts on your PC anyway, you can kill two birds with one stone by listening to the entire podcast within mp3DC and cutting the ads as you go. If you just want to kill one bird at a time, you can skim through the file with the arrow keys and page up / page down. Most people speak differently when they read an ad, or record the ad in a separate take. You can hear these difference as you skim even when jumping 10-30 seconds at a time. Listen for differences in intonation, room noise, or long segments of a single speaker instead of the show's usual back-and-forth dialogue. You will get faster as you get familiar with the podcaster's ad spacing and speech habits.
It is important to use a tool that does lossless copying, which means it doesn't re-encode the audio when saving the new file. If you use Audacity, for example, you are loading the mp3 into a wave in memory at the beginning, then encoding that wave back to mp3 at the end. Re-encoding will cause a slight loss in quality, though I admit it will not usually be noticeable. mp3DC copies the mp3 data directly. This comes with the limitation that you can only cut at frame boundaries, but that's ok because mp3 frames are usually ~26ms long, unlike video formats where keyframes might be many seconds apart.
The final step is to rest easy in the knowledge that no one can take the show away from you at this point. You can take as much time as you need to listen through it, and it'll always be right where you left it. As it should be.
If you do not have the tools or resources to perform these steps, I wouldn't mind doing it for you once or twice. Send me an email via writing@voussoir.net.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Here are all the youtube format codes I'm aware of. Please let me know if there are more, or if something here is outdated. contact@voussoir.net
You can pass them to youtube-dl as --format a+b/c+d/e
,
where a+b is your preferred video+audio pair, c+d is your second-best
preference, and e is your last resort.
Don't forget the magic words like "bestvideo", "bestaudio" to round out your selection.
See https://github.com/ytdl-org/youtube-dl/blob/master/README.md#format-selection
There are more formats listed in youtube-dl's source code,
but some of them seem to be obsolete and are no longer returned by -F
even when using the example video IDs listed there. I will only include
codes for which I have an example.
id | quality | codec | examples |
---|---|---|---|
571 | 4320p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
272 | 4320p30 | VP9 | youtube-dl -F i6fWG4FxDZw |
337 | 2160p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
401 | 2160p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
305 | 2160p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
315 | 2160p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
266 | 2160p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
313 | 2160p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
336 | 1440p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
400 | 1440p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
304 | 1440p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
308 | 1440p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
264 | 1440p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
271 | 1440p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
335 | 1080p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
399 | 1080p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
299 | 1080p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
303 | 1080p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
137 | 1080p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
248 | 1080p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
334 | 720p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
398 | 720p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
298 | 720p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
302 | 720p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
136 | 720p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
247 | 720p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
333 | 480p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
397 | 480p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
135 | 480p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
244 | 480p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
332 | 360p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
396 | 360p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
134 | 360p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
243 | 360p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
331 | 240p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
395 | 240p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
133 | 240p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
242 | 240p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
330 | 144p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
394 | 144p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
160 | 144p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
278 | 144p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
305 | 2160p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
266 | 2160p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
304 | 1440p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
264 | 1440p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
299 | 1080p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
137 | 1080p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
298 | 720p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
136 | 720p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
135 | 480p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
134 | 360p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
133 | 240p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
160 | 144p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
272 | 4320p30 | VP9 | youtube-dl -F i6fWG4FxDZw |
337 | 2160p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
315 | 2160p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
313 | 2160p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
336 | 1440p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
308 | 1440p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
271 | 1440p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
335 | 1080p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
303 | 1080p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
248 | 1080p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
334 | 720p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
302 | 720p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
247 | 720p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
333 | 480p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
244 | 480p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
332 | 360p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
243 | 360p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
331 | 240p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
242 | 240p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
330 | 144p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
278 | 144p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
571 | 4320p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
401 | 2160p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
400 | 1440p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
399 | 1080p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
398 | 720p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
397 | 480p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
396 | 360p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
395 | 240p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
394 | 144p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
571 | 4320p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
272 | 4320p30 | VP9 | youtube-dl -F i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
337 | 2160p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
305 | 2160p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
315 | 2160p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
401 | 2160p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
266 | 2160p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
313 | 2160p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
336 | 1440p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
304 | 1440p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
308 | 1440p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
400 | 1440p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
264 | 1440p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
271 | 1440p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
335 | 1080p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
299 | 1080p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
303 | 1080p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
399 | 1080p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
137 | 1080p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
248 | 1080p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
334 | 720p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
298 | 720p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
302 | 720p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
398 | 720p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
22 | 720p30+128k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
136 | 720p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
247 | 720p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
id | quality | codec | examples |
---|---|---|---|
333 | 480p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
135 | 480p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
244 | 480p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
397 | 480p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
332 | 360p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
18 | 360p30+96k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
134 | 360p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
243 | 360p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
396 | 360p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
331 | 240p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
133 | 240p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
242 | 240p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
395 | 240p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
330 | 144p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
160 | 144p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
278 | 144p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
394 | 144p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
571 | 4320p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
337 | 2160p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
305 | 2160p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
315 | 2160p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
401 | 2160p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
336 | 1440p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
304 | 1440p60 | AVC | youtube-dl -F -xNN-bJQ4vI |
308 | 1440p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
400 | 1440p60 | AV1 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ |
335 | 1080p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
299 | 1080p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
303 | 1080p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
399 | 1080p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
334 | 720p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
298 | 720p60 | AVC | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
302 | 720p60 | VP9 | youtube-dl -F 1La4QzGeaaQ -xNN-bJQ4vI |
398 | 720p60 | AV1 | youtube-dl -F 1La4QzGeaaQ |
333 | 480p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
332 | 360p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
331 | 240p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
330 | 144p60 HDR | VP9 | youtube-dl -F 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
272 | 4320p30 | VP9 | youtube-dl -F i6fWG4FxDZw |
266 | 2160p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
313 | 2160p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
264 | 1440p30 | AVC | youtube-dl -F -xNN-bJQ4vI i6fWG4FxDZw |
271 | 1440p30 | VP9 | youtube-dl -F kFz9afj8lu0 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
137 | 1080p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
248 | 1080p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
22 | 720p30+128k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
136 | 720p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
247 | 720p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
135 | 480p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
244 | 480p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
397 | 480p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
18 | 360p30+96k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
134 | 360p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
243 | 360p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
396 | 360p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
133 | 240p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
242 | 240p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
395 | 240p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
160 | 144p30 | AVC | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
278 | 144p30 | VP9 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ -xNN-bJQ4vI i6fWG4FxDZw |
394 | 144p30 | AV1 | youtube-dl -F S8Zt6cB_NPU 1La4QzGeaaQ |
id | quality | codec | examples |
---|---|---|---|
258 | 386k | m4a | youtube-dl -F NMANRHz4UAY |
256 | 195k | m4a | youtube-dl -F NMANRHz4UAY |
251 | 160k | Opus | youtube-dl -F S8Zt6cB_NPU |
140 | 128k | m4a | youtube-dl -F S8Zt6cB_NPU |
250 | 70k | Opus | youtube-dl -F S8Zt6cB_NPU |
249 | 50k | Opus | youtube-dl -F S8Zt6cB_NPU |
id | quality | codec | examples |
---|---|---|---|
22 | 720p30+128k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
18 | 360p30+96k | AVC+m4a | youtube-dl -F S8Zt6cB_NPU |
This document is generated programmatically.
sqlite3 :memory: ".read youtubedl_formats.sql" > youtubedl_formats.md
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I'm not satisfied with the new tab page on Android Chrome. So, I put together an html file that I can use as my own homepage. Here's a comparison:
I don't like the new tab page because:
Unfortunately, new tabs still always go to the new tab page and I have to hit the home button. So while it's not as seamless as I'd like, I can live with the one extra tap.
Here's what I did:
Create the html file, which is as follows:
<!DOCTYPE html5>
<html>
<head>
<title>Homepage</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
body
{
display: flex;
flex-direction: column;
}
a
{
display: flex;
align-items: center;
justify-content: center;
margin: 8px 0;
width: 100%;
height: 50px;
background-color: pink;
border-radius: 8px;
font-weight: bold;
font-family: sans-serif;
}
div
{
display: grid;
grid-auto-flow: column;
grid-gap: 8px;
}
</style>
</head>
<body>
<a href="https://example.com">Example</a>
<div>
<a href="https://example.com">Example</a>
<a href="https://example.com">Example</a>
</div>
<div>
<a href="https://example.com">Example</a>
<a href="https://example.com">Example</a>
<a href="https://example.com">Example</a>
</div>
</body>
</html>
Sync it between PC and phone with the amazing Syncthing.
Set it as the homepage using either file:///storage/emulated/0/<path>/homepage.html
or file:///mnt/sdcard/<path>/homepage.html
. Despite the name /sdcard/
, this path should correspond to internal storage.
Note: With Android 10's new scoped storage permissions, you may get a permission denied error while opening the page. Your first option is to place the file inside the Android/data/com.android.chrome
folder. E.g., an absolute path of file:///storage/emulated/0/Android/data/com.android.chrome/homepage.html
.
Alternatively, I was able to bypass the scoped storage system altogether with this ADB command: adb shell sm set-isolated-storage off
which rebooted the phone immediately and may have other consequences. I am not sure how it fares on Android 11.
Recently, I have been trying to use Android Firefox more, since it has extension support and thus uBlock. Astonishingly, Mozilla has removed the ability to set a homepage, which I believe occurred as part of the 2020-08-25 update. And their new tab page has an even bigger thing that I won't ever ever ever click on. I'm not sure what's going on over there.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>When people look at programming, they tend to say "That looks so complicated! I could never do that!". But you can. As long as you can describe how to do something step by step, then you have the ability to write a program. That's because writing programs is basically just writing down the steps to solve the problem, and letting the computer do it for you. You could follow the steps yourself and get the exact same result. You could even hire a bunch of schoolchildren for pennies on the dollar under the guise of "enrichment" to carry out your dastardly dictations... if you trust them to be as exacting as the computer, that is. Did you know that the word "computer" used to refer to people who did computations?
I think that everyone should learn some programming, but I don't think that everyone should become a "programmer". This is like knowing how to put gasoline in your car and air in your tires without being a mechanic; or knowing that protein is good for you and sugar is bad for you without being a nutritionist. Computers and digital files are now involved in just about everything we do, so being comfortable with them automatically improves your ability everywhere else. You will find that knowing a little bit of programming will suddenly be helpful in moments where you didn't expect you'd need it.
Don't think that programming is only for programmers. That's like thinking that reading is only for Literature majors. Capability with computers is the new literacy.
Most software we use today is designed to be used by hundreds, thousands, or millions of people. The creators of the software will try to solve the most common problems of the most common users. They'll make something that works "good enough" for almost everybody, though it won't be totally perfect for almost anybody. There will be something you want to do that the software doesn't have a button for. That's your problem, and it's up to you to solve it.
If you use computers at all for work, I'm sure you'll find cases where you wish you could improve the tools you have to work with. Recently, at my workplace, I've been writing javascript bookmarklets to add feature improvements to the web-based tools we have to use, so I get things done faster and more easily. And a lot of office jobs will have you working with a slew of document files, making small changes to each or converting them to some other format. This kind of repetitive task is perfect for programming. I recently wrote about one such example.
If you don't use computers for work, don't think you're off the hook. Programming will help you become disciplined in efficiency and planning ahead, and will give you a new vocabulary to express concepts you've probably already thought of. Vocabulary like latency versus throughput or bandwidth, parallel versus sequential tasks, the batching of similar tasks, and bringing down overhead. You'll notice real-life examples of abstractions and interfaces in the design and engineering of physical objects and structures.
This is not to guarantee that people will congratulate you on automating something, or promote you for doing it. But if you're working at a job you're not satisfied with, programming can turn a boring, rote, why-dont-they-replace-me-with-a-robot task into a fun puzzle that still winds up saving you time in the end. At any rate, I feel that being a strong critical thinker is its own reward while looking for something better.
I'll give some more of these down below.
When you give instructions to a computer, you have to be pretty specific. They don't exactly think by themselves, and they won't try to figure out what you really mean if your instructions are unclear. You can make a program called add
that actually subtracts, and the computer won't notice or care. If you feel that computers are becoming smarter than people, and you're worried about a cyberpocalyptic android takeover of Earth, just trick your computer into saying 7+3=4 and everything will seem okay again. For a while.
This means you'll be the one responsible for deciding if the results of your program actually make sense. You'll be the one ensuring that measurements of distance don't become negative, the clock doesn't show a 61st minute, and 7+3=10. You will encounter many unexpected problems while programming, and you will have to solve them. You will accidentally save a new version of the program while continuing to run the old one and wonder why your changes aren't making a difference. You will inadvertently swap left/right with up/down and see the world from a new, more horizontal perspective. You will gain practice in double checking not only your own work but the work of others, to figure out the exact step, possibly one of dozens, where an error was made. If you can combine these troubleshooting habits with good communications skills, you've got the makings to become a teacher, trainer, leader, or manager, wherever you are now.
As you spend more time programming, you'll find your ability to ask "what if" questions improving. In fact, it's very similar to arguing with someone and trying to poke holes in everything they say. Look for the weaknesses: This program divides two numbers; what if I type in zeroes? This program asks me for my birth year; what if I type in 9999 or HAHA? This program opens multiple urls as browser tabs; what if I give it a billion of them?
When you're the one writing the program, that means you need to predict the what-ifs that someone else [1] might try on your code, and armor up. Are you prepared to divide by zero, or deal with time travelers from the tenth millennium? This will be an exercise in recognizing your own assumptions and challenging them. This skillset will extend to your real life in the way you interpret arguments, politics, news stories, opinion pieces, advertising, and more.
This is why I have a hard time writing articles about my opinions. I am forever poised to either debunk my own claims or what-if my own thoughts, or else slather the whole article with enough disclaimers and qualifiers as to make the original point unintelligible. But this article is supposed to make you want to learn programming, so let's move on.
[1] You might think that if you're only writing programs for yourself to use, it doesn't matter because there is no "someone else". But just know that in six months you will totally forget how you made everything work, and you'll hope for your own sake that you made it idiot-proof.
Let's talk about literacy a little more. We are in a transitional period of history. When I was younger, everyone seemed to believe that my generation and all future generations would be naturally good with computers because we've grown up with them in our lives. But, in fact, that book is now shutting as fast as it opened. More and more kids are growing up with smartphones in their lives, but not computers. That shouldn't make a difference, because smartphones are just small computers. The thing is that smartphones were invented and developed from start to finish by corporations who have realized how much money there is to be made in an industry of locked-down devices, walled gardens, and advertising-driven-algorithmically-curated experiences. To continue the literacy metaphor, today's children are growing up with nothing but picture books. Desktop computers, on the other hand, are still carrying their heritage from the before days — the days of inspectibility, customizablilty, and programmability — because they were designed as a tool for solving your problems rather than dominating your attention. And when I say carrying their heritage, I mean reluctantly. Microsoft, Apple, and Google would love to drop desktop programmability in favor of locked-down devices if they could get away with it. They can't, though, because of all the existing software in the world relying on existing systems. Smartphones didn't have that burden, and look where they've ended up.
Learning a little bit of programming can be a breakthrough into realizing that the world of computers is not meant to be a theme park that you just wander around in. Computers and software are made by people just like you, and you are on equal ground with them. You can be an active participant in this world and mold your tools to work the way you want. Computers were designed to do work for you, though corporations will gladly continue to take that power away so they can show you more ads and sell you more junk.
It is liberating to say "This program/website doesn't let me do exactly what I'd like, but that's ok, I'll just fix it myself". You'll start to notice the ways software and publishers want to disempower you, and how you can reclaim the upper hand. Oh, you won't let me right-click the image to download it? That's ok, I've got Inspect Element. Won't let me read the whole article? Let's try spoofing googlebot's useragent. This program doesn't let me choose where it gets installed or stores its files? A few filesystem junctions will put that back in its place. No more waiting around for the software gods at the temple of Goog to eventually fix what's wrong, like you have to do on your smartphone, because you can fix it now.
Throughout history, corrupted leaders have used the illiteracy of their constituents to take advantage of them. This will happen to us digitally, too, if we do not cultivate tech literacy. I do rely on the tech leaders, after all. I'm not able to manufacture my own processors or write my own operating systems, so I need your help in defending what we've got from the current trend of eroding control.
Many aspects of computing and programming are interlinked, and it won't be possible to fully understand one part before you know many other parts too. That's okay. Become comfortable with the feeling that you don't understand everything that's going on, because it will be happening a lot. The important thing is to keep growing your web of knowledge and you'll discover how each piece links with the others.
In the beginning, don't buy textbooks. Don't enroll in courses or watch an entire video series. Don't look for a tutor. The first step is to develop your interest and a sense of accomplishment that gives you the motivation to continue. Motivation will be very important, and it comes from achievement. Solving real life problems that are relevant to you, no matter how small, are the perfect way of doing this. I guarantee that writing tiny, simple programs will feel amazing when the result is something that's actually useful and important to you. I am not saying to avoid textbooks forever, but they tend to make you do things that don't feel important yet. Save them for after you've found your footing and want to get a more rounded knowledge of programming as a subject.
Any time you find yourself thinking "doing the same thing over and over again is so boring, I wish I could do it all automatically", this is an immediate sign that you can program it.
But don't forget to have fun. If you find yourself saying "I wish I had a way to..."
wave
or Comic Sans.that's something else you can program for.
As I said earlier, you can write a program for anything as long as you can describe how to do it step by step. That means that whenever you want to write a program, the first thing you have to do is actually walk away from the computer and think about the problem. Talk through the steps, draw them out on paper, practice them physically, or instruct someone else to perform them as if they were your computer. Don't trick yourself into thinking you can make the computer do things that you yourself don't understand or can't describe. If you get into this mindset, you won't be able to live up to your own expectations which will kill your motivation.
As you try to describe the steps of your program, you will have to figure out how to make the computer understand what you want. You will find yourself searching the internet for "how to count words", "how to read webpage text", "how to only count each thing once", "how to save data to file", "difference between strings and ints and floats", "how to play video/audio file". You should never feel bad about looking these things up. Your job is not to become a memorization machine, but to know your problem and where to find the solution.
You will want a good text editor. I use Sublime Text 2, but I have heard good things about Microsoft's VS Code.
If you don't have access to a PC, but you do have an Android smartphone, try Termux. Though, I think you'll want to plug in a real keyboard.
Programs are written in a variety of programming languages. If you want to get started with programming, I recommend the following.
Javascript is the language that your web browser uses to make the page interactive. There is also HTML which contains the page content, and CSS which controls how it looks.
When you first start programming, it will be difficult to write a program from scratch. Instead, it will be easier to take an existing program, make a little change, and see what happens. Keep doing that over and over again with bigger and bigger changes, and pretty soon you're writing your own program. This is how I started too.
Well, the great thing about Javascript is that every website you visit already has a program that you can modify and play with! Just right click and choose "Inspect Element", or press F12, and check out the elements, console, network, and more.
Try making bookmarklets, which are pieces of Javascript code that you can save on your browser's bookmark bar, and then you just click them to activate it. The code goes in the place where you'd normally put the URL. For example, this bookmarklet automatically plays any video element on the page, which is great for forums with a lot of webms, and this one can rename the current tab, which is great when several tabs have the same name.
Also try making .html files on your computer and opening them in your browser. It's like creating a website without actually having to create a website. For example, this page I wrote shows new posts on a subreddit when they're made. You'll be amazed how simple it is to create something that could be described as a "web app".
A word of warning, though. The Javascript community has created dozens and dozens of frameworks and libraries and packages that they say you should use. Don't. For the time being, don't download anything, don't import anything, don't require
anything. No jQuery, no React, no nothing. The default javascript tools in your browser are enough to do what you want to do. The low barrier of entry to working with javascript is a great boon, but it also means the internet is overflowing with stuff people have made and shared, and it will be too confusing to navigate it all right now. Just have fun writing what achieves your goal. Stick to the standard stuff, and search MDN for how to use it. For example, here's the page on element.innerText.
Python has been my favorite programming language since I discovered it in 2014. I mentioned Javascript first because the accessibility of getting started is so much higher, but Python is where it's at if you need to write anything that isn't web browser based.
The standard library (modules and tools included with Python when you download it) are very capable so, like Javascript, you shouldn't have to worry about downloading other people's stuff to get started with the very basics.
I use Python for just about every facet of file management on my computer, like renaming all files in a folder, sending files to the recycle bin, clearing out empty folders, counting file extensions, and putting together ffmpeg commands that I wouldn't want to write by hand. I also crop, resize, and convert images to grayscale or the Windows .ico format. I love writing in Python and I hope you will too.
Once again, you can start by downloading somebody else's program and making small tweaks to it to see what happens. I find this more approachable than starting from a blank screen.
Although text editors and IDEs may let you run Python code within the editor, you will need to get comfortable with the command line to be most effective, so take the time to understand it.
AutoHotkey is in a different category than most programming languages, but I think it's excellent for programming learners to play around with because it's quite exciting to watch your mouse cursor fly around and do things by itself. For example, I once made an AHK script that would automatically click on the bonus items in Clicker Heroes, and a similar one for emptying my entire backpack into a chest in Minecraft.
The ability to create custom hotkeys really puts the Personal in Personal Computer. I have custom volume buttons, custom English/Korean keyboard swap buttons, and a button for keeping the current window always on top, which makes me feel like a wizard.
Also, AHK scripts tend to be short and sweet, so you don't get stuck on a particular project for too long, which is a good thing for learners. You can learn something, enjoy it, and move on.
The AHK syntax is a bit confusing, and I can never remember which of #
, ^
, !
, etc. I need to make my hotkey. But that's why there are docs.
Go get started. Have fun.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>In this document, C:\python
is the folder where you installed Python to. That's where python.exe
lives. C:\code
is a folder you created where you put all the .py
files that you make. Lastly, C:\anywhere
is anywhere else on your computer that is not one of these two locations.
I am using Windows style prompts with cwd>
. For Linux users, this is the same as your user:cwd$
.
python.exe myfile.py
(§)In this level, you are specifying the exact location of the Python executable and the exact location of the script.
C:\python> python.exe C:\code\myfile.py
C:\code> C:\python\python.exe myfile.py
C:\anywhere> C:\python\python.exe C:\code\myfile.py
python myfile.py
(§)In this level, you are letting the system find Python, but specifying the exact location of the script.
When you install Python, there is an option to add Python to your PATH. The PATH is a list of directories that your computer will search every time you type a command on the command prompt. This means that when you type python
, it will automatically find the python.exe in your installation folder. Windows users, type "environment variable" into your Windows search bar to open the settings menu and find the variable called PATH, or echo %PATH%
on the cmd to see what it looks like. Linux users, echo $PATH
.
C:\code> python myfile.py
C:\anywhere> python C:\code\myfile.py
myfile.py
(§)In this level, you are specifying the exact location of the script, but do not mention Python at all, because the system knows it is a Python file.
Windows: Ensure that .py
file extensions are associated with the python.exe or py.exe that you installed. This should happen automatically when you install Python, and you can always re-run the Python installer to reset these associations if they become broken.
C:\code> myfile.py
C:\anywhere> C:\code\myfile.py
Linux: Add a shebang for your Python executable to the top of the script file, and mark the file as executable with chmod +x myfile.py
.
/code$ ./myfile.py
/anywhere$ /code/myfile.py
myfile.py
on the PATH (§)In this level, you do not need to specify the exact path of the script ever.
Add the directory that contains the script, C:\code
, to your PATH. Remember that PATH is a list of directories, not files. If you add C:\code\myfile.py
, it won't work. You have to add the directory.
C:\anywhere> myfile.py
myfile
(§)The final level is to run Python scripts without specifying Python, or the extension, or the file's location. At this level, Python scripts feel like native commands such as dir
, ls
, and cd
.
Both: Add the directory that contains the script to your PATH.
Windows: Add .py
to your PATHEXT variable, so Windows will understand that when you type myfile
, it should also search the PATH for myfile.py
. Use where myfile
to double check that your file appears, and there is not another program with the same name taking priority.
Linux: Keep the shebang at the top of the file, and rename the file to remove the .py
extension. Use which myfile
to double check that it is the top result.
C:\anywhere> myfile
The only way to get better than this is to have a mind-controlled computer where you don't have to type anything.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>The internet has made self-taught learning more accessible than ever before. I am a strong proponent of self-teaching and using the internet to learn about anything you're interested in. But, the nature of internet learning also has its drawbacks, one of which I'm deeming the beginner bubble.
I think many people have had the experience of discovering a niche website written by a single, passionate person with an educational quality that puts textbooks to shame. Take for example Bartosz Ciechanowski - Lights and Shadows, a phenomenal rundown of the mechanics of light with beautiful interactive modules.
These kinds of websites are great, but they're hard to come by when you're intentionally looking for them. You'll see comments like "I wish I had found this when I was in school!". Outreach is hard for creators, and sifting through SEO and blogspam is hard for learners. Instead, we tend to compromise and use a common arena like Youtube instead of specialized websites and webrings. I would say that Youtube has become the de-facto home of internet learning in many ways, but it suffers greatly from the beginner bubble.
If I were to make a graph depicting the quantity of learning resources available to learners of different skill levels for a topic, which I have, then it would look like this, which it does:
There seems to be an endless supply of "for beginners", "intro to", and "how to get started with" tutorials online, and a very quick taper into obscurity beyond that. I am not saying that there are literally zero learning resources for advanced and expert learners, but take a quick dive into search queries like programming oop, git basics, or learn hangul and behold the open floodgates. Now, try again with advanced Python (the first things I see on the page are decidedly still beginner-level: "Overview of Python & How it Works", "Advanced Python 01 - lists / 02 - tuples", ...), advanced Korean grammar (notice, it's still mostly vocab lists or unhelpful vlogs). Higher level learning materials exist, but the number of beginner lessons is so totally dwarfing as to get my attention and provoke this article.
Let's start by giving everyone the benefit of the doubt.
Never heard of it: Any topic worth teaching will have some level of pre-requisite knowledge. It is difficult to give a meaningful lesson on Python to someone who doesn't know the basic concept of programming — it will devolve into a lesson on the basic concept of programming that just so happens to be demonstrated in Python. This prerequisite chain continues down to "what is a computer" and so on. So, creating lessons for Never heard of its is difficult because the creator must assume some level of background knowledge, and every creator may pick a different threshold. By virtue of creating a "Basics of Python, lesson 1", the creator inherently skips over people who have never heard of programming. That's not a bad thing, because nobody on the internet is obligated to create something they don't want to, and most likely there are others out there who will teach the basics of programming.
Not to mention, learners won't be seeking out learning material for topics they've literally never heard of. In order to access that demographic, the creator either has to present basic lessons on many topics and gain a "general learning" or "pop science" subscriber base, or hope that by sharing and word of mouth their lessons will reach the people who will be interested.
Beginner: Beginner level resources are the most numerous because of multiple natural tendencies by both the learners and creators.
Learners don't need very specific information and will be happy with anything as long as it's appropriate for their skill level. Each individual creator will have a different idea as to what they should put in their "beginner level" lessons, and the learner will use material from several creators to eventually get a well-rounded beginner-level understanding.
Learners need some time to decide whether or not they want to pursue the field further. They are probably searching for beginner materials just test the waters. After that, learners either drop out or spend more time with hands-on learning, reducing the demand for more advanced tutorial content.
Creators will usually start their lesson series by teaching the basics, instead of going straight for the advanced topics. Though they may continue to create higher level material too, others will stop creating, so the quantity of beginner resources will be the largest of all categories by default. Again, no one has an obligation to create if they don't want to, so someone who tries making tutorials may find they don't want to continue, and that's ok.
Creators who create for the beginner level will all start out in roughly the same place, then later branch out to fulfill specific niches. There comes a point where "Intermediate lesson on topic X" would be better titled "Beginner lesson on more advanced topic Y". For example, a first lesson on machine learning might require intermediate programming skills, but is better described as "Basics of machine learning" than a clumsy "Using intermediate programming to do machine learning". Learning materials will have a tendency to describe themselves as the basics of something rather than the intermediates of something. Thus, the bubble is partly a result of labeling.
Intermediate: I was careful to title the graph using the phrase "available to" and not "made for", because ultimately no matter how much content is made on the internet, discoverability and searchability is a critical factor in actually reaching anybody. One reason Intermediate material availability is low is that at this level, learning materials are specific enough, and require domain-specific keywords, that simply searching for "intermediate X tutorials" probably won't help the learner find what they're looking for. Any resources that are titled so simply probably contain a smattering of information bordering on beginner-intermediate but without the depth and specificity the learner actually wants. Learners must know some keywords to access what they need, which is difficult when you don't know what you don't know.
Expert: In addition to the searchability issue, the supply of expert-level lessons is low simply because the demand is low. Experts don't need lessons because they grow through actual experience and they know how to learn from source-level material. An expert programmer doesn't need tutorials on how to use a library because they can read the documentation or source code. An expert artist doesn't need more drawing lessons because they can establish their own style and innovate new techniques.
It's time to get critical of the situation, because I've noticed behaviors and patterns from creators that don't line up with the generous interpretation. Although the beginner bubble is the observable, physical product of creator behavior, I feel that creator behavior itself can often be described as a beginner tar pit. From the point of view of an internet creator with less-than-noble goals, it is best if the audience remains stuck at the beginner level.
To start with, I accept the fact that the beginner audience is simply the largest audience. I believe what I said about learners and creators dropping out, and learners not needing as many tutorials as they advance. There's nothing wrong with that being true. I don't think the resource graph should be flat. However, I've noticed some creators who stay in the beginner bubble far longer than necessary. I find myself trying to assess whether the creator is genuinely passionate about teaching their subject and helping learners advance their skills, or whether they just make lessons for youtube views, ad dollars, book sales, course sales, etc.
The bubble continues to balloon, because:
Anyone can do it: The barrier to entry for publishing online is getting lower and lower. Overall, that's a good thing, but it also means that creators can start teaching before they are anything more than a beginner themselves. Some people are just a little too eager to start explaining things to others, and during their second week of learning about a topic will happily make tutorials for everything they learned in their first week. At this stage, the creator lacks the big picture context that would allow them to make smart decisions about what to teach or omit. Their lessons will be regurgitations of whatever lessons they've received, without understanding how the information actually pieces together. I have had to resist this urge many times, and I've failed many others.
Those who can, do: And those who can't, talk about doing. The only people capable of creating expert-level teaching material are the experts, and where are they? They're out practicing their craft, of course; continuing to hone their skills and furthering their career doing what they're an expert at. Real experts don't have as much time to faff about with internet tutorials as people who like to pretend that they're experts.
They can sell you stuff: Not only are beginners the largest demographic, they are disproportionately more willing to spend on resources than learners at higher skill levels. This is partly because they haven't reached the moment of disillusionment that learning requires significant time and effort and not just the buying of books, and partly because they cannot yet assess the quality of the resource being sold to them. If a beginner buys a low quality resource that's difficult to learn from, they might think the topic is just hard. Higher level learners will have better BS detectors and less patience for low quality material.
Scammers around the world prey on the ignorant, and "educational" scammers are no different. You can find videos online of magical polyglots spitting phrases in a dozen languages they supposedly learned to fluency in six months each. And for just $14.99, you can have access to their course showing how they got there.
Here's a quote I discovered on hn which is half relevant and all poignant:
Writing for money and reservation of copyright are, at bottom, the ruin of literature. No one writes anything that is worth writing, unless he writes entirely for the sake of his subject. What an inestimable boon it would be, if in every branch of literature there were only a few books, but those excellent! This can never happen, as long as money is to be made by writing. It seems as though the money lay under a curse; for every author degenerates as soon as he begins to put pen to paper in any way for the sake of gain. The best works of the greatest men all come from the time when they had to write for nothing or for very little.
If the reader wishes to study any subject, let him beware of rushing to the newest books upon it, and confining his attention to them alone, under the notion that science is always advancing, and that the old books have been drawn upon in the writing of the new. They have been drawn upon, it is true; but how? The writer of the new book often does not understand the old books thoroughly, and yet he is unwilling to take their exact words; so he bungles them, and says in his own bad way that which has been said very much better and more clearly by the old writers, who wrote from their own lively knowledge of the subject
Arthur Schopenhauer, "On Authorship"
Immunity to criticism: Resources for beginners will naturally need to smooth over some details to keep the lesson understandable, but that becomes decreasingly acceptable as you reach expert level materials. Creators who can't teach the fine details or don't want to deal with criticism will find safety in the beginner tar pit. As long as the lesson is labeled as "for beginners", then it becomes immune to any criticisms that details are missing, edge cases aren't covered, specifics are left vague, and examples feel artificial. You'll hear "I know I skipped over that, I just wanted to keep it simple".
Not only are beginner resources more immune to criticism, but they attract less criticism in the first place since the audience, by design, consists of people who know little on the subject. It doesn't matter if the magical polyglot horribly mangles the pronunciation of their dozen languages if the listener doesn't know the right pronunciation either. You don't have to be very skilled to impress at this level, which feels good for the creator.
I'm different: I know I'm a jerk for raining on people's parades, but as I swim through a seemingly endless supply of Lesson Ones, it's clear to me that the majority of creators on the internet are fantastically, myopically unaware of just how many people have already beat them to the punch, or just don't care. It is somewhat mind boggling to me that people don't stop to think "I wonder if anyone else has already made a tutorial about this" before making their own and tossing it onto the mountainous heap. Or they do think about it, but decide that their version is somehow different and special. More realistically, they didn't actually look at what already exists, because they're here to be Mr Teacher, not to learn what's already out there.
Sure, again, we remind ourselves that anyone can make whatever they want. I'm going to stop adding that disclaimer now. It's true that teaching others is a great way to help oneself learn, so maybe a lot of it boils down to that. Still, it's fascinating to me from a sociology point of view that creators either don't consider or realize the oceanic scale of the internet, and the fact that their idea has probably already been done and done better [1]; or they do realize that but go ahead with it anyway.
Is it for ego, to have their name on the page and not someone else's? Is it for practice, to get comfortable writing and speaking and editing? Is it because they'd rather spend 3 hours making their own tutorial than 20 minutes reading another and just sharing that link? Do they genuinely think they bring something new to the table, even on basic and rote topics? But, wait a minute, none of these desires require that we stay in the tar pit — couldn't we get the same ego boost and speaking practice and enjoyment of creation by making something besides another Lesson One? Something actually unique? [2] The answer is most obviously yes, and yet here we are. The number of collective man-hours spent spinning our wheels on remaking the same Lesson Ones is disappointing. I'm not asking for people to be robotic and completely deferential to the anonymous mass of the internet, with only one tutorial in the whole world for any given subject, but the situation has got my mind turning and I'm becoming increasingly self-aware about whether I'm being novel enough in what I publish.
When I am programming, I often find situations where there is an existing tool to do what I need, but I would rather have the enjoyment and control of making my own. This is surely similar, though I would note that I publish them without making any false gestures that I'm doing it for the benefit of some audience. I publish them because its free and easy and doesn't bother anyone else since my repos get no visitors anyway.
Low commitment: When it comes to beginner-level information, there's never a single correct order to present the many concepts. Knowledge is a web without a clear starting point. It is natural that a teacher will present many ideas which at first seem unrelated, and the connections become clear as the lessons progress. However, if the creator is not committed to helping learners grow their knowledge web, they have the option of instead continuously bouncing around their repertoire of beginner lessons without actually developing the connections. If the learner doesn't perceive the connections, and every lesson is presented to them as if it were novel, they may not realize they're being held in the tar pit when they could be advancing.
Contrast that with someone who shows, say, how to build a house from the ground up, or how to go from Nand to Tetris. In those cases, there's a clear starting point (empty lot, nand) and a clear ending point (house, tetris), and if the creator doesn't reach the ending point it will be obvious to every onlooker. Abandonment and unfinished business is more apparent at the expert level. Creators who aren't confident or committed in their teaching can stay in the tar pit.
Audience pull: My tone in this section largely paints these beginner-level resource creators as malicious — as intentionally trying to keep learners stuck in the tar pit for their own personal gain. And for the scammer types that's true, but I must clarify that some creators wind up staying in the tar pit without consciously choosing to. Take for example a creator who makes a couple of beginner lessons, then starts receiving comments and emails from learners requesting a lesson on some other beginner topic. Repeat a few times. The problem is that the collective intelligence of the requests never really rises because the audience churns and new beginners make new requests, and randos on the internet are very bad at using search bars for some reason, so they wind up requesting the same things over and over again. For the creator, it feels good to be getting recognition, and they'll want to please the crowd by fulfilling those requests, without putting their foot down about the direction they want to take their creation. Plus, again, beginners are the biggest audience, creating disproportional feedback towards beginner level topic requests.
[1] The brain has not yet become accustomed to the light which the internet has shone upon it: it's very, very hard to come up with anything original.
[2] inb4 this article is not unique either.
Talk To Me In Korean is the inspiration for this article. With over 1,600 videos already on the channel and some dozens of courses on the site, they continue to astound me by releasing videos like How to make Korean sentences (for absolute beginners). In the past six months, they have greatly ramped up production on their "Live Korean Class" series, which are hour-long meanders through a general topic. The individual teaching moments that occur throughout the livestreams will of course be valuable to somebody, but with such low information density, searchability, and conciseness of theme, they are useless to someone serious about learning the language. These are for people who want to feel like they spent an hour studying, without putting in an hour's effort.
Every couple of weeks they publish a video reminding you to buy their books.
TTMIK's best product is undoubtedly Iyagi, a now-defunct podcast which totaled 145 episodes of pure, no-English, normal-speed Korean speech plus full transcripts. At one point, all the episodes were freely available and I downloaded them. Now they're behind a paywall, because TTMIK realized that their podcast from 8-10 years ago is of higher value than the hours and hours of video they make now. Their old videos are pretty hilarious, too. As always, it's the business that spoiled the product.
Duolingo has a reputation for people using it to study on a daily basis, sometimes for months or years, without making significant meaningful progress. Yes, we can blame the learners for only using a single resource, and only using it for a few minutes a day. But Duolingo's reputation in this regard far overshadows any similar examples I can think of. There's clearly something about Duolingo's formula that encourages the learner to feel as if they're being productive without actually helping them out of the bubble. Part of that comes down to their advertising, and part of it is their UI's positive tone and encouragement without reminders to study harder with other resources too.
Forgive me if I don't provide too many other case studies of bad examples. I don't actually want to bully individuals, and these days I don't read / watch enough tutorial content to know names of popular creators. TTMIK just brought it out of me. Let's share some positives instead.
Thomas Frank has created a respectable channel and I am happy for his success. Spreading the word about learning and motivation is nothing but a good thing. You can tell, though, that his video topics tend to repeat, probably partially as a result of fan requests. For a general topic like "college level studying" of course I expect everything to stay rather basic and widely applicable, but I think Frank's channel is a good example of the pressure to publish exceeding the number of new topics to explore in the space.
GO! Billy Korean is a great guy and I admire his passion for teaching. He usually doesn't get into highly advanced lessons, but he gets into intermediates with his language and culture trends videos. He even goes through the effort of cutting down his live 2-hour classes into 12-minute abridged versions, which I know for a fact is not a quick thing to do. His videos are straight to the point and he very, very rarely mentions his paid books or patreon. His primary lesson videos are short enough and well-titled. My only criticism is that he seems to have put a hold on his primary series of 113 episodes to start a new beginner course, which is a bit of a circle back into the tar pit.
ultimateKOREAN is a champion of lesson quality. How often do you see actual bibliographic citations in a youtube video description? Although the specific dialogues that he teaches with are often above my level, his explanations give me clear insight on what I should look out for as I continue to learn. He is careful to note that grammar taught in textbooks is not the same as grammar used in real life, and always presents multiple possible reasons why a certain grammar construction would be used. In the comments of A deep look at 잖아, he says "I love doing this but at the same time I somewhat feel discouraged when other channels get more views for less informative content". Please show him your appreciation.
Ben Krasnow aka Applied Science doesn't make 'lessons' per se, but he is undeniably a natural teacher. Everything he does is filled with genuine interest and the utmost respect for the viewers. He knows exactly how to progress the viewer's understanding from Never Heard of It to a reasonable understanding (for a sub-30 minute video) without ever dumbing down the scientific terminology. When he's experimenting with something, he always points out room for improvement and possible future applications to stimulate the imagination.
3Blue1Brown makes animated math videos and publishes the code he makes them with. His goal is to clear away the magical haze that blocks peoples' understanding of math by showing how complicated systems can be represented with clear, intuitive visuals. His lessons are awesome and he's awesome.
Bill Hammack aka The Engineer Guy is a clear communicator who shows the fascinating internals and design of things we take for granted, often with a poetic bent. It's hard to pick a single best video, so check out Nitinol, Plastic injection molding and Aluminum cans.
Ian LaSpina aka Knyght Errant participates in Medieval Living History events and makes videos about medieval culture, arms, and armor. Although I never considered myself to be very interested in history, I was absolutely absorbed by his Palazzo Ducale Bascinet video and quickly binged his whole channel.
To creators who are passionate about teaching: Know that there is an audience who desires higher level learning material. Know that a thoughtful and powerful lesson maintains its value and rewatchability for a long time, although the overall view count will be lower than the cheap stuff. Rewatching well-presented lessons is a pleasure in itself, and I frequently rewatch videos on the channels mentioned here just for fun. Know that as the creator, your channel is your ship to steer and you don't need to be pulled back by audience requests.
To creators who are passionate about making money: Nothing I can say will change your mind.
To learners: Recognize when you are being held in a tar pit. Diversify your learning sources so as to know the strengths and weaknesses of each. Encourage creators who do good work, because they need to hear your appreciation. Support them on patreon etc. if you want to go the extra mile.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Today, I had 57 png images of QR codes, and needed to create a single pdf document where each page contained a single QR code with the file's name shown centered above the QR. From start to finish, without planning ahead, it took me 23 minutes, a pace which would have required me to do 1 image every 24 seconds if I were to do them by hand. Plus, any subsequent tweaks can be done in a flash.
Create one svg manually
Generate svgs for all other images
Create a Python file, and start by:
TEMPLATE = '''
paste the svg file here
'''.strip()
If you chose to embed the image, it will be stored as base64. In that case, delete the actual base64 text, but leave the data:image/png;base64,
prefix. After the comma, add {image_base64}
.
xlink:href="data:image/png;base64,{image_base64}"
If you chose to link the image, you'll find the file path. Replace it with {image_path}
.
xlink:href="{image_path}"
Find the element that contains the label text, and replace the text with {label_text}
.
The rest of the Python script was as follows:
import base64
import glob
filenames = glob.glob('*.png')
for filename in filenames:
label_text = f'...' # do some transformations on the filename
data = open(filename, 'rb').read()
image_base64 = base64.b64encode(data).decode('ascii')
svg = TEMPLATE.format(image_base64=image_base64, label_text=label_text)
open(filename.replace('.png', '.svg'), 'w').write(svg)
Using linking instead of embedding, this would have been more like:
for filename in filenames:
label_text = f'...' # do some transformations on the filename
svg = TEMPLATE.format(image_path=filename, label_text=label_text)
open(filename.replace('.png', '.svg'), 'w').write(svg)
Convert svgs to pdf
On Windows, a for-loop in the command line looks like this:
for %x in (*.png) do (start /w inkscape --without-gui --export-pdf=%~nx.pdf %~nx.svg)
Combine all pages into single pdf
pdftk *.pdf cat output "all.pdf"
If I need to make any updates to the template, I can
{templating}
.If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>When it comes to forming opinions, nobody can sit down and critically analyze every opinion and belief that they hold, myself included of course. And that's understandable, because there are just so many opinionable topics in our lives that we simply have to prioritize what to think about and leave the rest to instinct, upbringing, and whim. Otherwise we'd be doing nothing but opinionating.
The phrase "standing on the shoulders of giants" gets thrown around a lot, to the point that I'm pretty desensitized to it now. After all, it's true for just about every aspect of everything, and it sounds poetic, so it gets repeated. But occasionally I will sit down and try to think critically about a topic I want to form an opinion on only to get lost, tangled, and overwhelmed in the details.
It's one thing to stand on the giants, it's another to look down.
These articles are dedicated to those topics. Topics where the underlying, primordial elements sound reasonable but the current, evolved state of affairs is objectionable, and for the life of me I can't find the line in between. Topics where I'm supposed to pick the best course of action to help the most people but every path seems wrong for one reason or another.
A small group of people get together and say "Hey, hospital visits are usually more expensive than I can afford at any given time, but they're very rare. If we all agree to share some money in a pool, then we'll each be putting money in and each be getting benefits out, so it comes out fair and makes us all safer". And lo, private health insurance is born.
I know what you're thinking: the government to which these people pay taxes should already be serving this purpose so they wouldn't feel financially endangered in the first place. But hold that thought because that's where the lost, tangled, and overwhelmed part is going to come in. Anyway, that's what the situation ought to be and not what it is. On its face, there's nothing so wrong with the actions of these people: they saw a problem in their lives and banded together to solve it. Surely a small group like this wouldn't think they could influence the government to enact socialized healthcare, and if they did try to go that route they would be unprotected in the meantime. Foreshadowing alert: there's nothing more permanent than a temporary solution.
For this nascent health insurance collective to operate, they'll have to calculate some statistics regarding the frequency of hospital visits and the cost of those visits so they can divide it up and have everyone pay a bill each month into the central pool. If the collective is being lead ethically, it won't be seeking excessive profit or hoarding money for its own sake. That can be a big if but this is a theoretical piece.
At some point, someone new comes along who wants to join the collective. This person has some kind of health condition and needs frequent, expensive treatment. The statistics on which the other members' payments were decided weren't calibrated for this. The collective will have two choices: provide this person with the same level of coverage and premium as everyone else, even though it won't be enough for their higher bills; or increase everyone's premium so that this person receives the same level of care, proportionally.
It does seem unfair to treat the newcomer differently than anybody who's already in the group. Life is unpredictable, and it's possible that anyone in the collective can develop this kind of expensive condition at some point. But, if they've got a contract with their insurance that prevents their premium from increasing, then that's part of the financial risk that the insurance collective accepted when they formed and calculated the rates. Now we're talking about someone who has a pre-existing condition [1], which gives the insurance the luxury of deciding whether to accept or deny their application.
What should they do? Nobody wants that person to be in pain (or worse, die), but if this is a private group who have all agreed to share their private money, they're well within their rights to decline the new member. Nobody can force you to accept someone into your club, right? I hesitate to write this because it sounds so bad, but it's true. Everybody would have to pay more without getting any additional benefits because the new member would be taking out a disproportionate amount, which will certainly lead to sour feelings (if they're sour enough, they could splinter off and form a new group with the original rates) even if it's for the greater good of humanity by helping this new member. It's not easy to convince people to give up more of their money for the good of humanity [2].
The only entity that can force the insurance collective to accept the new member would be the government. Gov could say "let everyone in without discrimination or else your collective is illegal" and poof, it's play along or disband (or be outlaws. Healthy outlaws). The likelihood of government taking notice of the collective grows as the collective itself grows and more members start to depend on it. This is especially true if the collective grows so big as to overtake competing insurers, such that the marginalized groups of people with pre-existing conditions have even fewer choices of insurance collectives to join.
Competing insurers? What? Why do they need to compete? In the primordial state, the collective is made up of people whose full-time job is something else. There's probably a leader who had the idea to form the collective in the first place, and a person who's good with stats to calculate the bills. In this state there's not much reason to 'compete' with other groups doing the same thing. That's like competing with the adjacent neighborhood to see who can share more sugar. But as more people join, someone's going to have to step up and become a full-time leader or treasurer or statistician to manage the collective and its money pool. As soon as that happens, and they've quit their day job, their livelihood relies on the insurance collective in more ways than one, and now the group definitely needs an income stream greater than their outbound stream, and that means they need to compete.
If insurers want to compete by offering low rates, they'll want to exclude people with pre-existing conditions. Insurers that accept expensive people will charge expensive premiums, and only expensive people will be joining them.
You know I don't normally cite things in these articles but this passage says exactly I'm thinking:
In the absence of regulatory interventions in a Private Health Insurance market, insurers might tend to adopt practices that seek to minimise their risk to avoid losses, including denial of coverage for applicants who have preexisting health conditions (Kofman 2006). On the other hand, overregulation might exert enormous stress on insurers, resulting in strangulation of the market (a situation whereby insurance schemes are unable to function in a sustainable manner and therefore are forced to shut down) (Sekhri 2005b).
Government regulation of private health insurance (2015) [pdf]
The idea of government regulating the practices of private insurance, to me, sounds like a joke. But not the funny kind, I mean the dumb kind. Firstly, because if the government wants everybody to have an equal opportunity at receiving healthcare, then... why is that not part of the taxes? And secondly because it forces every insurance collective to converge toward a single point, where every insurer is nothing more than a new face and logo on top of a singular system known as government-approved operating practices and non-discriminatory membership. Even in the primordial state, insurance collectives have very little room for flavor — put money in, get money out, the amounts of which are based on the stats of the collective's demographic. The only flavor is the demographic. So the reckless skateboarder whose membership application into the Stay At Home Knitters Health Insurance collective was rejected will instead have to stay in the Reckless Skateboarders collective, with appropriately higher rates which correspond to the cost of living that lifestyle. An insurer that casts a wide demographic net will, by definition, see the cheaper members subsidizing the more expensive members, while a narrow demographic net will charge rates that more accurately reflect the costs of the member, which may be quite high if you live a dangerous lifestyle.
Notice that if the entire collective consists of people making frequent withdrawals, whether they're reckless skateboarders or people with expensive medical conditions, then the whole concept of amortizing costs falls apart as members are making deposits and just as quickly turning them around for withdrawal. The premiums at that point must become as expensive as the bills they cover, and everyone is essentially paying their own bills indirectly through the insurance. Cheap members must subsidize expensive members in order for the concept of the insurance's cost amortization to work.
Unlike the reckless skateboarders, people with expensive pre-existing conditions didn't choose that lifestyle. Under a self-segregating and self-pricing private system, there is logically no collective who would enthusiastically accept the pre-existing condition people, who introduce a high cost through no fault of their own. Realistically, the only way to give these people reliable support (which they deserve, as we all do) within our society is for it to be mandated by government, thus washing away the only variable that could distinguish the collectives in the first place.
Oh, and that's not to mention the practical arms race that occurs between hospitals and insurers, where the price of everything inflates so comically high that non-insured people don't stand a chance, certainly not those with expensive conditions. Once insurance becomes commonplace, hospitals can raise their prices through the ceiling because who cares haha the insurance will pay for it. And the individuals, because they're paying indirectly through their insurance premiums, and only encounter the hospital under bad circumstances, have little leverage.
I know that there are people who oppose government-run healthcare because it brings the word "socialism" to mind. They'll certainly feel embarrassed when they realize that the entire concept of any insurance at all is based on the socialized distribution of risk and funds. Sure, government health insurance is socialistic and private health insurance is not-socialistic, if you need to draw a strict political distinguishing line. But practically, it's difficult to say the current free market of health insurance really does what free markets are thought to do. 49% of Americans get their health insurance from their employer, so they're stuck with their employer's choice of insurance provider and plan unless they want to go it alone. The other 51% are, I suppose, self-funding their insurance, or covered under government Medicare, or simply don't have any. It's only some portion of that 51% that's exercising their ability to shop around for insurances (which, again, have few legitimate ways of distinguishing themselves), but it's 100% of us that get caught in the pricing arms race and in-network hospital requirements; and it's the people with pre-existing conditions who deal with the anxiety of only maybe being covered.
REMEMBER: there's nothing more permanent than a temporary solution. It would be great we if could go back in time, to the moment the first private health insurance collective was formed, and say Hey no, start a movement for government-run tax-funded healthcare instead, or else we're going to wind up with a bunch of vaguely unique health insurance companies acting as proxies for the government's wishes under tight regulation except taking a privatized slice off the top of your bill every month [3]. But now every aspect of this system is so tightly intertwined, especially with regards to that pricing arms race, that it's easier for the government to regulate private insurers into acting like government bodies than to actually fix healthcare as a government body.
BUT, that's not what's on the ballots. You know what's on the ballots? "Should insurers be required to accept pre-existing conditions [_] Yes [_] No". Oh my god. If I say yes I'm allowing the government to get away with yet again lazily slapping more restrictions on private insurers instead of saddling up and creating a tax-based healthcare which is obviously what this is supposed to be, contributing to the decay I've described above, and encroaching on the rights of private people in private groups to do with their private money what they wish. And if I say no, people will die.
[1] A note about this vocabulary. There is a movement around "Being a woman is not a pre-existing condition", and other "____ is not a pre-existing condition" sentiments. The word condition here really poisons the tone because in common speech it almost always means sickness or illness or something wrong with you. If you re-interpret pre-existing conditions from the point of view of the insurer as meaning "there is some fact about you which is visible from the outset and changes our expectations about the amount of coverage you're going to cost us", then it's very easy to conclude that their statisticians have, for whatever reason, found that people who are or who have ____ cost them more coverage than their median member. Does that mean I'm happy to see people get charged higher premiums for something that they can't change about themselves? Of course not. This is where we get into distributing costs among the wide demographic, or letting the narrow demographic pay different rates closer to their expenditures. After thinking about this for as long as I have, I can't help but see these people as being angry at statistics, though the vocabulary doesn't help either. They might do better to redirect their anger towards the government for not making a national health insurance, since the private sector is where these demographic-specific statistics take effect. If the entire population is under a single insurance, there are no demographic lines any more. Under private health insurance, understanding what your rates should be is nigh impossible with the information gap between regular people and the insurers who invest billions into collecting stats on their target demographic. Under national health insurance, your rates derive from national expenditure divided by population size.
[2] So, why do I keep saying that tax-funded healthcare is okay? Isn't that exactly "giving up more money for the good of humanity"? This is an area where the tangibility, the line-of-sight to the cost, has a big psychological impact. Even though we can look at the government's spending of our taxes and deduce that X% of my Y dollars was spent on roads, and X% was spent on schools, I for one don't really feel those percentages. Taxes are more like a black box where money goes in and results come out. Case in point: if taxes were paid as itemized bills, and every citizen in the US received a separate "Bombs to Drop on Countries that Have Oil we Want" bill in the mail, they'd be shocked and outraged. But taxes aren't itemized like that, and the fact of the matter is we're all paying this Bombs tax already, but few think about it and even fewer complain. For the rest, it's invisible. If healthcare were migrated into taxes, I do assume it would wind up being cheaper, but at the very least it would be invisible like the Bombs tax and people would stop complaining about it so much.
[3] Why do I sound so sure that a government-run insurance would be cheaper than private insurance? The government is not known for its economic efficiency. Firstly, private insurance companies have costs that a government insurance wouldn't have, such as advertising. Here are a couple of numbers about that (one, two). Secondly, and probably more impactful, I expect that if the government was the one paying out for coverages, they wouldn't give in to the pricing arms race game that hospitals want to play. Another technique the industry uses to reduce individual power is to create partnerships between insurers and hospitals, and to establish "service areas", within which you should go to an insurer-sanctioned hospital or else they won't cover the visit. Much of this wouldn't be possible when there's only a single insurer in the nation.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>[git] [meta] [today_i_did_this]
When I started writing these articles (you know, 2 weeks ago), I decided to put them into subdirectories for broad categories: python
, life
, and computers
are what I had so far. For example, /writing/life/friction
.
Because this site is statically generated from the directory tree, moving files and folders around would change their URL, so once I put an article into a category it would be stuck there unless I was willing to break the link. The reasoning for making category folders was:
continue
statement as python/continue
, I could later create java/continue
if need be. I wouldn't have to cautiously prefix every article like python_continue
.Today, however, I decided that the cons outweighed the pros because:
So I decided to move everything out of the category dirs. Since this site is new and nobody has any links to it yet, it's better to break them now and get it over with. But because git history and commit timestamps are central to my publishing model, I needed to keep that intact or else lose all this soon-to-be-nostalgic early history.
There are plenty of tutorials on the internet for modifying git history. This is just a short description of what I did today in case I needed to do it again sometime so I'll have a reference.
[1] I do think category systems can have a place alongside tags. Will expand on this in the future.
I zipped up the repository so even if I mess everything up I could extract it back and start over.
The commands used in the following steps will use sed
and linux style environment variables and linux style single quotes around some commands, so Windows users should run bash.exe
which is located alongside git.exe
in your git installation folder.
The original paths were like /writing/life/friction/friction.md
and I needed to turn them into /writing/friction/friction.md
. Just needed to replace /life/, /python/, and /computers/ with /.
I found this stackoverflow answer which quotes a premade snippet from the docs:
To move the whole tree into a subdirectory, or remove it from there:
git filter-branch --index-filter \ 'git ls-files -s | sed "s-\t\"*-&newsubdir/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
The SO comments mention that using hyphen as the sed separator is flaky so I went ahead and used #
instead without even trying -
. I assume the escaped \"
is for filepaths with spaces, but it didn't help in my case so I removed it. For me, the command was was:
git filter-branch --index-filter \
'git ls-files -s | sed "s#/life/#/#" | sed "s#/python/#/#" | sed "s#/computers/#/#" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Since filter-branch is dangerous, make sure to test out the git ls-files -s | sed
commands separately first.
However this was raising an error during the final mv
step because the index.new file referenced by the variable didn't exist. I'm not sure if it was supposed to exist already since the snippet from the docs doesn't mention it. I found this SO answer saying to just add ; /bin/true
to just ignore that, so the final error value is 0 and git doesn't abort.
git filter-branch --index-filter \
'git ls-files -s | sed "s#/life/#/#" | sed "s#/python/#/#" | sed "s#/computers/#/#" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; /bin/true' HEAD
This worked and now all the paths were correct. But the articles themselves contained links that I needed to fix.
I used git rebase -i commithash
where commithash was just before the earliest case of an article that contained a link. I set commits to e
if they involved an article that had a link.
Rebase e
performed the commits in question — adding or editing the article — and then paused the rebase so that I could edit the link in the article to just /writing/friction
, then do a git commit --amend
so the change became part of the commit as if it was correct all along.
This left authorship dates intact but set commit dates to be the current time.
Rebase has a flag called --committer-date-is-author-date
to copy the author date to the commit date, which is what I needed. For some reason this cannot be used with -i
simultaneously, but simply running a new rebase with this flag and no other changes fixed it up.
git rebase --committer-date-is-author-date commithash
Then to publish,
On my side:
git push origin master --force
and on the server side:
git fetch --all
git reset --hard origin/master
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>I have always hated writing. You've heard people say "I'm so bad at math", but I have said "I'm so bad at writing" just as many times. If my English teachers saw that I had begun writing voluntarily I think some of them would be shocked, and some of them would say I had the capacity but never the drive.
My grammar in these articles is probably not great. In one English class my professor pointed out that I make comma splices on almost every page. I have an affinity for turning things into bullet pointed or numbered lists which in somes cases is the best presentation for the material but in other cases is a cop-out to avoid prose. I have no problem writing sentence fragments. Or overusing em-dashes and parentheses. And I start sentences with conjunctions. For some reason I have a fascination with stringing together very long hyphenated phrases in an I-wish-I-had-an-adjective-to-use-here-but-I-guess-I'll-have-to-make-my-own kind of way. But the fact that this page you're reading even exists is a testament to the fact that I have decided to prioritize expressing myself and reaching people rather than writing "well" or following any particular structure.
Generally I think that programming can be an art form. The choices of naming, indentation, docstring formatting, quantity and quality of comments, and API design are all areas rife with opinionation and the ability to impress. Or at least the ability to enrage when they are bad. Code can last a long time and have wide-reaching impact. I am proud of the code that I write, and I write it with the expectation that it will be read, not just run. Experimental ideas get the # WARNING: Bad code ahead!
treatment but for the most part I think I do a good job.
The problem is I can't share the joy of my work with anyone who isn't also a programmer, which is most people. They won't understand the work that goes into it, the decisions I made and how they compare with the alternatives, the extensibility and modularity of my design, the consistency of my whitespace, or how excellently the comments explain the rationale behind some particular particularity. I can spend several hours putting an application together, and no matter how useful it is to me [1], the most I'll get out of friends or family is "oh, cool". It's worse for backend code, where there's no visible product whatsoever besides the code itself. Not even other programmers will be interested in reading through that unless they expect to find something novel or some accidentally-published credentials to borrow.
What did you do today? Um, well, I have a program that helps me organize ebooks and it had a problem so I spent about three hours fixing it. Oh, cool.
I'm not totally detached — I know that musicians, authors, filmmakers, actors, dancers, visual artists, architects, and engineers of all trades experience this exact same feeling. I know that cutting room floors are messy the world over. I've seen Misery so I know the blood, sweat, and tears that go into writing a book. But for most of these, you have an end product which people understand, recognize, contemplate, compliment, love, hate, collect, burn, sing along to, cry over, are frightened by, have revelations through, make videos about, wear, get tattoos of, and decorate their homes with. The only time programs really wow non-programmers is when they output art or music and in that case it's not the program they care about. I sympathize with security professionals, technical support, and janitors whose job it is to remain invisible.
I have likened programming to art, but really it is more like craftsmanship. If a craftsman makes a beautiful hammer, other craftsmen can appreciate it but most people will just want to hit things with it... which is its purpose, after all, but if only they would enjoy it a little more?
This is why I have decided to start writing these articles. I have many ideas and though I am absolutely fraught with counter-counter-thoughts, I'm doing it anyway so that I can feel like I've actually used the thoughts for something instead of letting them be forgotten in timid silence. I want to have something to show non-programmers for what I do and what I think. To explain my interest in such-and-such technology in some way other than "here's a git repository I made for that".
[1] This section is basically me whining about not getting enough praise so let me clarify. I write programs because I enjoy it and because they benefit me. Here's a bunch of scripts unlikely to be read by anyone, but which represent the me-shaped indentation I've left on my computer like a bed that you slept on too long. The more things I automate, the more time I have left over to... search for something else to automate. It's just that, let's face it, sometimes I wish I could show code to people and have them say "wow, nice!".
This isn't to say that I've done nothing but programming and am just now trying something else for a change.
Drawing: I'm not a super great artist but I have always enjoyed doodling. I have a digitizer tablet which I mostly use as a mouse-substitute but I enjoy doing digital sketching, and I like the additional handwritten flair when I need to annotate screenshots instead of using MS Paint text.
Youtube: I was 15/16 when Minecraft lets-plays became huge on the internet. My computer at the time didn't get very good framerates, so although I tried recording a few lets-play style videos I knew it wasn't really worthy of publishing. Instead I made some tutorials about redstone and worldedit because subpar framerates are tolerable if the lesson is good. As I got older I was not happy with how my voice sounded in those videos, and did not want people finding them, so I deleted them both from youtube and my computer.
I later did some tutorials for writing reddit bots with PRAW, but when PRAW moved from v3 to v4, those videos became obsolete and I decided to unlist them.
The only valuable video left on my channel is 22n - 1 = 3k and I would like to do more in this vein. I've always enjoyed kinetic typography videos (one, two, three, four, five, six) and educational math channels. 3B1B was already big by this time.
Many of the articles I write here are things that I would like to make videos about. But while text is cheap and gittable, videos are not, so I think this is the better way to start.
Minecraft otherwise: My first real programming experience beyond .bat files was in Java, which I had to learn in order to make mods for Minecraft. I made my own ores, tools, plants, and trees. About 30% of the items I made had some semblance of legitimate purpose, the rest were because I had come up with some pixel art that I liked and wanted to make an item for it. If you want to see some python projects that spawned out of my Minecraft interest, see VoxelSphereGenerator and Minecraft3DVector.
TF2: I have 1700 hours in TF2. Some hundreds of those are from idling to get refined metal back when it was 2.33 per key. Out of the active play hours, I'd say at least 90%+ were spent on cp_orange_x3 or variant maps. There was a server with a 100% crits mod that I played on regularly, and when I made my own orange map cp_orange_Skyward they were kind enough to host it and I became a moderator on the server. Here are some screenshots of Skyward (one, two, three, four) and I will see about cleaning up the messy vmf and uploading that.
Making texture replacement skins for TF2 is pretty easy, but for a bigger challenge I tried Blender to make a hat. I only got so far (one, two) before giving up, but at least I can say I've used Blender.
Future ideas:
A little more than a year ago I discovered the world of fan-made film commentaries. The first one I saw was David Taylor's Birdman commentary, then I discovered Tysto and popcornpoops and a few others. I think this is an awesome idea and I've wanted to make some ever since, but I haven't gotten around to it yet. You have to find enough interesting things to talk about to make it worthwhile.
Paul Graham's articles, particularly Why Nerds are Unpopular and The Age of the Essay. Thank you Paul for helping me realize that writing can be approachable, and that the 5-paragraph assignments from school have wrongly commandeered the word essay.
David Foster Wallace. I learned about DFW via Will Schoder's video The Problem with Irony. Then I read DFW's E unibus pluram (1993) and Brief Interviews with Hideous Men (2000) and watched this interview he did on German tv. I have not read any of his other works yet but I will get to them in time.
I don't read books very often. The number of books I've read on my own accord is very small. So maybe I'll sound like a noob discovering the best thing since sliced bread. Having said that, Brief Interviews is one of the few things I've ever read where I was actually amazed at what I was seeing. I say "seeing" and not "reading" because at the moment I'm not even talking about the message, but rather the formatting, the torrent of footnotes and asides, the introduction of terms like [flexion of upraised fingers to signify tone quotes] which over the course of a few pages shortens to [finger flexion] then [f.f.], the unabashed reuse of chapter titles and recurring segments, and the chapter Datum Centurio which is written like an excerpt from a dictionary from 2096 with an obscenely overwrought system of superscripts, daggers, subsections, IPA, and index cross-references (KEY at BABE, CYBER-). Suddenly my poor use of the comma doesn't seem so bad. Reading this book is like watching 2001's stargate sequence or Beyond the Black Rainbow or House or Let the Corpses Tan to some extent. I have always had a tendency to overuse parenthetical asides, but my growing affection for footnotes is thanks to DFW.
I hear that James Joyce is similar and will likewise get around to reading his work.
Similarly, gwern.net. The funny thing is I don't actually read gwern, I've read maybe one or two articles in total. I consider it an influence because he also goes very heavy on the markup formatting and asides (in fact, between the icons indicating the domain of every link, and the asides which physically crowd the main article, I'd say it's a bit too much for me), and I particularly like that there's almost always code snippets, graphs & charts, even embedded audio clips in some cases. I would like to add more rich media to my writing too, but because this website is saved as a git repository, I'm perpetually hyper-aware of the don't store binaries in git! fairy reminding me that the repo size is going to bloat if I do that. Maybe I should put the files on s3 and just link them here? But then the site becomes more fragile and loses its cohesion as a cloneable, offlineable, full website? We'll see what happens. Hmm but I'm linking to third parties too so maybe I need to be archiving those links like gwern does.
I also like that Gwern articles invariably link to multiple other Gwern articles, in a twisted web not unlike the brain itself which spawned it.
danluu.com for keeping the most minimal plaintext blog I've ever seen. So much so that I have to use Stylus to give the page a column width or else it's cinemascope levels of head turning to read.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>This page collects comments which make unnecessary or tenuous analogies to computers, programming, dollar-sign $variables, sed's/replace/syntax/g, mathematics, AI/machine learning, and cryptography in discussions that aren't about those things.
Agreed, but that's a two part issue.
#1 - The modern web has a much lower ratio of citizenCreators : consumers than the early web.
#2 - The utility of information is professionalUnbiased > proHobbyist > professionalBiased > randomPerson >> SEO spam.
Google's current ranking is SEO spam >> professionalBiased > professionalUnbiased >> proHobbyist > randomPerson.
That's a clear misalignment.
Sadly, due to being on the first floor* I don't have a lawn.
I do keep considering balcony mounts for what would've been the lawn defence cannon though.
* en_UK first floor, mind, I know en_US insists on 1-based indexing rather than 0-based for floors but I don't particularly like writing FORTRAN either.
s/at the speed of light/no faster than the speed of light/
Also, what is with this misconception: "When twins aren’t being regarded as carbon copies, they are slotted (or slot themselves) into opposing roles." Dude, any vector can be projected onto another one, with an orthogonal ("opposing") component left over.
Layoffs in the WFH era are weird. Back in the day you had a pretty good idea of who got laid off because you saw them walking out the door with a box of their stuff. You could go up to them and say, "hey let's meet at $local_watering_hole and hang out". You could swap contact info if you didn't already have it.
On far older hardware, we still used spinning rust for $deity sake...
Once you understand the embryology, there are actually a variety of things like the appendix: they're just the ends of things that come together. The uvula is a great example: embryologically, the two sides of the face separate very early as an opening, then develop a lot of complicated anatomy and fuse back together. The uvula is where that fusion completes and the fusion process completes (returns 0) when the microenvironment variables get to a certain state.
The ability to shutdown any persons the government doesn't like using any growing list of $Excuses is worrying.
I have a couple of examples (of HN and high-ranking HNers natch ;) and found a fair number of bugs^H^H^H^H non-optimal choices in their feeds, probably because XML is not all that human-readable, even for devs.
I will admit, I've often searched for $project_name github to get to their repositories. It shouldn't matter but it's just a force of habit now.
Xiaomi is China's Apple, so what happened to the rumored Apple car? Haven't heard anything for a while, but Wikipedia claims it's still planned for 2024-25:
Yeah, under the hood that date is {{Date().getFullYear() + 1}}
Calling it: Apple will partner with an established automaker such as Goldman Sachs^H^H^H^H^H^H^H^H^H^H^H^H^HPolestar and customize the infotainment OS.
Inc actually does this sort of madlibs article all the time
"In $NUMBER (words/sentences), $FOO taught a masterclass in $BAR"
You're positing that some significant portion of the victims decide to settle like this:
if (shame)
But it's almost certainly this:
if (bankruptcy_risk || shame)
I actually don't benefit at all from you using my code; I did all the work to make the world a place where $PROBLEM has an accessible solution.
At $DAY_JOB we recently scuttled most development efforts for a week for our teams. Our nightly backup job that sanitizes PHI ballooned overtime to, say, 20GB+1Byte and ran out of disk space. Because we are running Kubernetes on Fargate we don’t need a full time operations guy, right?
I'm ashamed to admit I often wonder about this when playingˆHˆHˆHˆHˆHˆHˆH my daughter plays with myˆHˆH her Duplo train.
I have no dog in this fight as I rarely deal with cash and do not run a retail business. However from a conceptual point of view I really have a viscerally negative reaction to not accepting cash. It is a societal acceptance of the rent seeking behavior of the credit processing networks. I already have to pay a sales tax to ${TAX_ENTITIES.length} different government entities, I don't love that I also have a 3% tax going to VISA/Mastercard/Amex/...
Anyone who uses ChatGPT for a while will learn to take everything with a grain of salt.
s/Grain/huge rock/
Addendum: don’t rely on your git/wiki/document-system for tracking the timestamp. "This was accurate on $DATE" has a very different meaning than "this document was last edited on $DATE". It might be 2 years out of date but someone fixed a typo last week.
or s/bottled water/water bottles
Also, adding a charger for your swappable-battery car costs pennies, so lots of people won't even use their car's battery a swapping feature (which is really bad for battery swapping outlets). If most people only use the battery-swap at Christmas and $HOLIDAY, then the networks could be underprovisioned during those spikes and overprovisioned in the other 363 days of the year.
Horrible edge cases to consider when dealing with music
title += " publishing metadata"
That video is wrong. Men who are actually friends don't tell each other "that's a nice tie", they tell each other "nice tie $SLUR".
struggles with too many files. Last I looked, official Microsoft documentation says to not exceed 100k files. Yet, $WORK wants to dump basically every file I touch inside there. My Teams folder alone is ~20k files.
Tuta became understandably a walled garden that my other tools couldn't easily work with. This wasted alot of my time.
Nowadays using $normalemailprovider with Thunderbird.
But having a favourite release of Mac OSX means it's Snow Leopard. I've seen comparisons between $current and $current_minus_one, but never in regards to "That was my favourite" - likely because anyone invested enough in Mac OS releases to have a favourite, favours Snow Leopard.
Sure. But the $CURRENT_MODEL's price never decreases. It stays steady - until the next price bump. E.g. $MID_RANGE_GPU, $HIGH_END_CPU - their price will decrease next year, when the new model comes out. The new model's price will not be lower than the current one.
I now guess somebody wrote it up, published it and maybe linked to it on Twitter, some content-farming bots notice $ACTRESS_NAME trending on Twitter, and their algorithm realize there's audience eyeballs to be gained there, and found the freshest article about her, on Twitter I suppose?
s/China's TikTok users/Users of China's TikTok/
Also starting to realise that my "they can't stop me gaming when I'm 80!" attitude will be self-limited by joint pain at some point... probably in exactly the same way as previous generations, just s/gaming/popular activity of the era/
Calm down satan. Until you manage to manufacture physical products for free (one time cost then get inf copies, as digital content) retail theft !== digital pirating
From someone that occasionally visits YouTube, hearing people talk about YouTube this and YouTube that numerous times in one conversation let alone in a day is very noticeable. Same thing goes for Reddit. Or TikTok. Or any $socialMediaPlatform.
It's been a while now since I used a self-checkout, but my general philosophy is "Sorry, $Employer pays me to fight with buggy, UI-from-hell computers at $Job. If you want me to fight with your self-checkout system, my rate is \$$Lots/hour".
s/Spending/Stocking Up/
I'd pinged HN mods about this, though dang ended up dong a wholesale replacement rather than s/She/Sabine Hossenfelder/.
It really does sound weird. I already imagine trying to sell this at my $DAYJOB (I would likely have to "fork" it myself just to replace a few strings in the codebase that mention the original name).
Ask HN: What programming languages are you using at $WORK?
If you search "watch $MOVIE free" on google you're going to get netflix, Hulu, prime, Disney etc as the first results regardless of whether those sites even have it in their library.
I hope these journalists are ashamed of themselves and I hope they are at least sacked, with their careers relegated to selling poutine all day.
s/selling/eating/ ?
There is always plenty wrong with each new release but the comments and jokes about ${"LATEST_RELEASE"} of ${"SOFTWARE"} being unilaterally bad just make me think the person can't deal with change instead of the software actually being bad.
I'm scratching my head here. The old gas/diesel dispensing stations have solved this problem of restricting people taking all of the fuel in the pump with a disruptive financial technology called blo^H^H^H credit card.
With that said, it's been a reliable solution and does not need me or my friends to create $BIGTECH account.
I am endlessly annoyed by slow interfaces. At $DAYJOB I have to use a web and desktop GUI for managing CheckPoint firewalls. These often will freeze for dozens of seconds, and generally make my computer crawl. I feel that this should not be acceptable in 2023.
Quite. s/"thanks to abusive users"/"thanks to an abusive provider".
So Dutch is little-endian?
s/world/US
God I hate the business models of $CURRENT_YEAR
If you don't care about the notifications anyways....then turn them off/silence them. Switch from an event-based model to a polling one, since you're treating it that way anyways.
I don't live in a country where it's as one-dimensional as: (public road) ⇒ ¬(privacy rights) and I value that.
An "Architect" was pushing SMS 2FA for our application, and only SMS 2FA. Like you I pointed out all the issues. The response I got was "well if it's good enough for $BIGCORP it is good enough for us" and I didn't win. Cargo culting at it's finest.
Imagine scraping by to pay rent from your minimum wage job, and you're told that you can't sign up for $SERVICE because you don't have a new enough phone or a yubikey.
s/Unfortunately/Thankfully/ but a great point!
Just FYI, discord.io !== discord.com the chat app, it's a related but separate service.
s/receives/sentenced to/
"Receives $X years" Is an idiomatic way of expressing prison terms.
There are many websites that provide exactly that function. I suspect most of them are based yt-dl{,p}.
Reading 3 books on $topic will give you a deeper understanding and appreciation for $topic than 99.9% of the population. Yet you are still at basically zero compared to the people who wrote those books.
It was one of her tweets, it's on wikipedia and was widely "reported" at the time. It came in the context of her late conversion to Islam, and the blowback it generated (imagine being a high-profile personality in a deeply $religion-following country, and publicly abiuring that to become $aVeryDifferentReligion...).
I don't think the author is trying to spur you to action. Like most articles, it's meant to make you think.
s/think/click/.
"We switched to $BUZZWORD and reduced $LOOSELY_UNDERSTOOD_METRIC by $STIMULATING_NUMBER !"
Never tell them it's just because of all the technical debt you finally had organizational will to pay off.
We've had great luck at $CURJOB with forum software.
Why have a geofilter if the vast majority of people are logging into the site to see if anyone is talking shit about $COMPANY and the only way to make money is if $COMPANY pays you off to take those posts down?
> On a PC laptop it often is. Even on many all in ones now.
s/even/especially/
Facebook^W Meta is scum.
People who don't own $valuable_asset believe that it should be regulated and there should be mechanisms in place so that everyone has some $valuable_asset.
How does one go about getting such numbers? Do a web search for "$BANK_NAME virtual credit card number"?
It's supposedly a mere slip slope from there to every restaurant and grocer in town refusing to sell food to members of $Disadvantaged_Group, causing them to die of starvation.
But no, now that the market has been oligopolized, it's more profitable to show you what you don't want, and you'll have to be satisfied with whatever incidental successes you manage while wading through the output of the Search^h^h^h^h^h Sell-You-Things Engine.
If, when it really matters, the actual & on-hand operating staff for $SYSTEM cannot understand even basics of the controls for $SYSTEM - then you're control UI is a complete failure, and you'll end up f*cked.
I have also started looking at it, by $REAL_JOB doesn't leave that much time.
Something I've always wondered is how people actually do the backwards alphabet test. I don't think I could efficiently do it sober, but I do have an O(n2) algorithm for doing it; sing the ABCs in your head, and only say the letter before the one you've already said.
So this means that /r/$FOO is not actually a subreddit about $FOO, moderated so that exactly any non-spam discussion about $FOO is allowed, but rather a dictatorship ran by whoever happened to grab the name first.
if you don't like the actions of mods on a subreddit you can just make another subreddit (including in your company example, if the company does /r/$NEWPRODUCT and removes all negative opinions people can easily to /r/$NEWPRODUCT-community and run it as they wish instead)
I was just thinking that this weekend in the Seattle area as we wandered the aisles for six for the wife. It's either an attempt to put the scariest-looking skull(s) on the label, or $SOMETHING $SEXUAL_REFERENCE $FARM_ANIMAL (e. g., Ass-Kickin' Horny Goat Stout).
Legitimately seems like a GPT-tier confusion. Just put all the somewhat-relevant words in a syntactically correct configuration and call it done.
Half a decade? Hasn't it been going on for well over 40 years by this point?
s/decade/century/
Please stop. These discussions never lead anywhere, and all they reveal in the end is that $SOME_AI_PROJECT doesn't meet $YOUR_IDIOSYNCRATIC_DEFINITION_OF_AI.
Time to enjoy some sweet O_2 molecules.
s/guy/woman
s/West/USA/
possible with the current deepf^Wparody technology
This Python dictionary could be useful for $HOBBYIST who is learning about $HOBBY and could help people familiar with $HOBBY to remember terms or use it for guidance in improving their skills at $HOBBY.
Newspapers do the kind of in depth investigation as their bread in butter that other mediums rarely if ever participate in.
s/do/did/
Oh dear $deity. Why does it insist on capitalizing "and" in the middle of a sentence?
Atheist as in "has replaced $god with some gnostic belief system", no thanks.
At $job-4 I had the following exchange with HR
The form this argument always takes is:
1) undesirable_outcome will not happen, and here's a rational argument why.
2) ok, undesirable_outcome did happen but it wasn't undesirable in the first place and here's a rational argument why
Adding a "if user lives in $city then he probably won't stay in a hotel in $city" would have a positive impact in all Google Maps users
Maybe they're a LLM and got confused by the keyword "conspiracy theory" and the double negative in the statement.
edit: s/meandering/rambling
Or just today I saw "$PROJECT is used by these awesome projects"
So complaints about rootkits^W anti-cheat is a banned topic now?
And he was really struck at first, like "Why would you write Hello World when we're building a $WHATEVER?"
Then he should be a $POSITION at $BIGCORP.
More realistically, you're more likely to hit "yes if there is compelling evidence that $choice is better than $status_quo with respect to $criteria".
> It really cannot be overstated enough the wealth divide that pandemic QE created.
:s/\\<created\>.$/exacerbated./
At $oldjob, taking care of a busy and successful web estate that is now close to 25 years old, one of the ugliest and longest-standing warts was the "image store". That was a simple, flat directory on a single node, shared over NFS, which had accumulated more than 1.2 million (yes, 1_200_000) inodes/files in a single directory.
Also s/produce/release/g
Wow, now that's a case of paint^W checkering oneself into a corner.
s/popular/common/ I sometimes wish portrait oriented 4:3 monitors had become the dominant form.
I couldn't supply enough work for the contractors (we had to rush into it because ${life reasons}, so not everything was specced out when the work started)
IIUC this is what iMessage does (at least when Messages in iCloud or whatever it's called is disabled), except s/people/devices:
I work at $LARGE_CORPORATION and our product a11y team's most recent major ship was a new palette of colors with improved contrast ratios.
Welp, looks like that tweet got censored^Wdeleted.
s/tiktok/uber/g
The comments on the site have become predictable enough to be GPT generated.
My personal experience with devs who don't want to GPL their code or contribute to GPL projects is that they're under the impression that having a permissive license on their own project will get $corp to use it and, somehow, they'll profit from $corp using it.
s/Android/Windows/ and s/Europe/USA/ and it could be Microsoft at the end of the antitrust case in the 90s.
Large vehicles are safer for vehicle-on-vehicle or vehicle-on-object crashes, and vehicle-on-pedestrian crashes are a very small fraction of total fatal crashes. The core objection of this blog post^H^H^H^H^H^H^H^H paper is nonsense.
I love stories of little quirky & fable-like people who are known as "that X person", and they seem to be a master at whatever X is. Creates a real charming atmosphere wherever these people exist.
I imagine some of us are those kind of X persons in other peoples lives, where X ∈ {Computer, Science, Internet}.
#upvotes !~ effort put into comment
Telling X and doing !X is not a recent invention.
Forgive me if I'm wrong but I suspect this comment is GPT3 generated. Regardless, it was hilariously absurd.
I'm sure this is good, like, really really good, but I'm struck by the feeling that it wants to baby talk me the same way Godel, Escher, Bach did.
I mean, it reads like a Homestuck pesterlog.
Perhaps it's written by GPT-3..
If I see someone is typing in a Slack channel, or typing to me privately, it takes all my focus away until it is complete.
that means a person can DOS you by typing and erasing text but never sending you a message?
Identifying this usage would require the compiler to be aware of the version control system, and still wouldn't correctly identify that the version sent from $COWORKER via email for some weird reason isn't a gradual change.
Is this a GPT-3 generated post? It reads like an answer to a completely different different question that just happens to hit the same keywords (e.g. "pay", "smart", "comfort", "social class"...)
I couldn't download .exe files at some $CORPORATION. They had to be whitelisted or something, and the download just wouldn't work otherwise.
I'm quite sure similar services can also be used by the average person. You simply google for these magical words '産廃業者 $CITY'.
> It might sound silly but I'm always amazed at the fresh perspectives I'm able to obtain when I ask "someone smarter" for advice in my imagination.
That sounds eerily like asking GPT3 to pretend to be someone else.
But we're all living in the same system, and to put it in HN terms, we need to wipe and reinstall the OS.
The only switch type where actuation == tactile feedback that I know of is buckling-spring, as in the IBM model M.
I've always said it's not the Tree of Life, but rather the DAG of Life.
I still don't understand why this is a website thing and not an user-agent^W^W webbrowser thing.
My $DAYJOB task this week is beginning the process of splitting up a 14554 line C++ file.
At $prevjob we had the ability to do things like this at the push of a button, and generally would have within 90min of incident onset to help systems heal.
Correct. "Not doing $X anymore" doesn't mean you aren't an addict. "Being able to turn on/turn off doing $X" means you aren't an addict.
Note this is amending existing law, so think of it as a legal diff.
This native English speaker is with you, I thought RacquetNext was some new-fangled racquetball racket that was banned because it has carbon fiber plates that…do $SOMETHING, ala the Nike Vaporfly/Alphafly running shoes.
At this point, the onus is to prove thing $x is not used for Google analytics.
I don't think people do this because they want to be polite. The 'hello' is basically the start of what is the human equivalent of the TCP three way handshake.
- Hello (SYN)
> Hi (ACK)
- How are you doing ? (SYN, ACK)
Basically, they are trying to set up a synchronous channel over what is essentially an asynchronous medium. This is even more annoying than just slowing down the answer, they are demanding your undivided attention during the conversation.
You know you are on HN when hello/hi is explained in terms of SYN/ACK and not the other way around
I tried their "Best toaster" query and one thing I want to say is just how hilarious it is that "best x"-of-anything webpage HAS to have $CURRENT_YEAR in the title. Yelp does something similar to its Google search results.
As if nothing good or the best in its breed ever came out from $PREVIOUS_YEAR or any previous years before that!
Tell me you're a garbage SEO website without telling me, just slap on "in $CURRENT_YEAR" or use some capital letters, I love how easy it is to tell the wheat from the chaff!
Best $PRODUCT $CURRENT_YEAR can include products that were manufactured in $PREVIOUS_YEAR or $LONG_TIME_AGO. The $CURRENT_YEAR is saying that the list is up to date, not that all the items in the list were made in $CURRENT_YEAR.
There is a joke I love that illustrates the concept: "Ladies and gentlemen of the jury, my client was nowhere near the scene of the murder, he didn't mean to pull the trigger, and that son-of-a-bitch had it coming!"
What would that be in programmer speak?
The intern had no write access to the production database, he didn't mean to do the commit, and our network engineers had it coming?
A new version with s/Stalin/Putin/ would be good, and perhaps given oligarchs etc. even funnier.
When I'm tired and out of time instead of ordering an unhealthy meal from $FOODDELIVERYAPP$ I can (and very frequently do) buy something relatively healthier from such a site.
But, every $BIG_CORP out there has on their roadmap a long-term plan to either drastically reduce their spend on Oracle products, or more often, eliminate it entirely.
It's kind of terrible that you can use extensions XOR your own browser on iOS
I'm currently job hunting, and a bit tired of sending out 3 - 5 apps a day via indeed or $COMPANY_SITE. Actually talking to someone would be nice.
I immediately came home, tried logging into my online banking accounts, but couldn't due to 2FA. Of course, I won't be able to log in until a replacement phone arrives.
It's the same failure mode if you s/phone/token/.
There is nothing in any dishwasher, fridge, vacuum cleaner, washing machine, ${you_name_the_home_appliance} that would require to be smarter than they are without those (actually far from smart) hardware and software that is being installed and imposed on customers.
Typo in the headline: s/DNA/NDA/
I distro hop with my home laptops and use Windows at $JOB
> If we assume that both groups visit government websites equally often
My pattern matching experience from real life tells me that this is unlikely....
The blog post misunderstand that many people that do that are simply using "hello" as a "ping" to see if someone's really there for immediate synchronous communication. They want to type just 1 word first ... and then wait for a human-style-TCP-ACKnowledgement
Some grouping or merging of URLs for major news would be nice, though hard to implement. For example Apple releases a new product, new version of Firefox, new S1 filing of $unicorn.
Yes, crows use poke, dig, find, free, head, tail, touch, more, mount, make. And if they don't like you, they use kill. Sometimes even killall.
crows are unable to use git, but then even I was unable to use git right after onboarding.
Unbounded extensibility is a great way to get adoption of a standard, in the sense that a lot of products will say "Fully $standard Compatible!" in their marketing materials. It is a bad way to ensure that the standard actually means anything outside the marketing materials.
Then again, I've used mailing lists since UUCP and VMS, so maybe I'm just exp^Wold.
English is the javascript of languages: full of warts and enforcing a status quo that sucks but everyone has to learn it because this is the world we live in.
Esperanto would be like Haskell: beautifully pure and regular but no one uses it except for a passionate community of die-hard zealots.
Romance languages would be like scripting languages (Python, Ruby, lua, etc.): once you know one the others get really easy.
Greek would be like Lisp: had a lot of influence on current languages, dwindled a bit, but is still around.
Biology is what happens when you try to decompile code written in assembler into OO language.
True statement. I lost a finger tip in a mandolin making potatoes lyonnaise. It mostly grew back. However, it has never felt the same. It's like the nerve endings in the finger tip throw unhandled exceptions.
A lot of therapists have a two year degree.
What's your point?
It's important to be careful about to whom you grant root access to your mind.
For desktops HTTP2 is mostly ok, possibly an improvement. For Mobile it wasn't. I raised this when we were trailing in at $financial_media_company.
Normally I have to rely on reddit posts or random blogs that I find with search terms like "$gameType game with no P2P/P2W" or "$gameType game with no IAP" but even that's not perfect.
Sounds like Tamlin's 'assistant, a lawyer' is an id^H^H^H^H hasn't spent much time in the bush.
Reads like it was written by GPT-3.
At my $OLDJOB, I used ImageMagick to compare snapshots during some automated front-end testing on our public Drupal site.
I'm perfectly happy to use my brain as an index instead of a data warehouse. As in, I don't bother committing to memory things that I can reach out and grab if they fall out of my "cache".
The problem for me now is my mental index can suffer from link rot.
s/Browser/Chrome/, please.
Spaces in filenames were a mistake to begin with.
Spaces are used to separate parameters in the command line. There's also no real need for filenames to support spaces.
If I have some solution that can solve some major $PROBLEM, but a side effect of that solution is that some small group of people "get paid to do nothing", I'm completely OK with that.
Nginx is making the same mistakes that dethroned Apache. No one wants to fiddle with a web server. Default to $currentIndustryStandard, make it work, forward to my application.
Messaging apps are more like postal services — "please deliver this message to $person" — you're describing driving across town to drop something in a mailbox directly.
I suspect that you don't work at $BIG_CO and rather something more startup-y?
> Whales have the capability to far outstrip humans in intelligence (if you accept that neuron count and neuron connections are the raw inputs).
Understood normally, the raw input also includes the software installed in the whale's brain. This limits the potential capability of whales.
If you were to overwrite that with software of your own design, you'd have a robot in the body of a whale, but not an actual whale.
Using it everyday too at $work, also used Slack and Gitter (and FreeNode/IRC FWIW).
Literally everything you wrote applies exactly the same if you s/E.164 number/email address/g and s/SMS/email/g
That's not really fair. You can want to have an "open enough" collaborative community without a trillion dollar company ($cloud_provider) steamrolling you and your work.
I was having to compete with professional spammers^H^H^H marketers for my friend's attention. It's gross.
We use that gateway email address with our notification alert system at $WORK.
Also, the page you were actually looking for is probably https://...
I appreciate that you might think that, and thank you, but I was only interested in the 404 page.
ML fails again. They need better training data
If you had to hazard a guess, what $EnterpriseVideoconferencingSuite would be most amenable to this sort of work?
> Which is of course a fairly hard problem to solve - if you aren't having 2.2 children per couple then your population is shrinking.
You can increase throughput with parallelization or speedups of single threaded performance.
> Anyone who really wants to stop a gaming addiction can stop it - it is only a question of will.
| sed "s/gaming/drug/"
Continuing to support $x means continuing to defend attack surface that's implemented as $y year-old code, to deliver a feature that in $z the majority of people do not use
Back when I worked at $HEALTHCARE_INUSRANCE_CO we were trying to solve this (more general problem) from the other side.
s/make it impossible/make it prohibitively expensive/
An interesting, short read is the difference between Emergency Use Authorization (EUA) and the full FDA approval.
Basically it is manufacturing, funding and red tape being the difference, nothing about safety or clinical trials differs.
In software terms, EUA is parallel tracked sprints for clinical trials and manufacturing at same time vs. regular approval is Waterfall where manufacturing occurs after approval.
s/Carlie/Charlie/, I assume?
If a NN is equivalent to $sophisticated_algorithm, that's a positive, not a negative.
In general he thinks a lot about tool kits and I think what we're seeing here is the math equivalent to being great at debugging.
Yep. I have a buddy who works at $BIG_US_RETAILER and he weekly has to go into the stock room with a box cutter and scissors to destroy unsold clothing.
Also, at $WORK we have three separate but related products, each with separate version numbers that we jumped at some point to reach the same value across all 3.
Ask HN: Which "old" programming language(s) you still use in your $DAYJOB?
That's a result of mindset and approach. Japanese can't focus on 2 or more problems, neither they can assess influence of one issue against another and see an ecosystem.
Yeah sort of lacking the concept of hierarchy and/or recursion. "We need Z to do Y to do X" - no no the operand can't be a pointer to executable address. That'll fault.
It shouldn't take horrific accidents for us to suddenly decide to care about structural safety.
The problem is the same as it is in IT.
a few years ago at $dayjob we had a fleet of CoreOS hosts.
While the topic is certainly interesting, the way that this article is written feels odd. It reads (to me) like GPT-generated text.
s/for JS/on NPM/
In the case above it wanted me to write out "That fly was sitting on something weird" - but I had written "That fly was sitting on something unusual" which is a perfectly valid interpretation of the sentence, but because they basically did a strcmp() I got it "wrong".
I've written on HN before about relatively simple things I have found useful (keeping a diary in $language, or watching films with $language audio)
Is this why I always get text messages from one of my friends that say > Liked "{$ENTIRE_CONTENTS_OF_PREVIOUS_MESSAGE}"?
I remember when win2k was "the last good windows" and then windows xp after it. I $CURRENT-2 is always going to be considered "the last good windows".
Bureaucracy isn't that different from code. Some of it's dead legacy that needs to be removed, some of it's legacy that needs to be improved/replaced, some of it's legacy that's good enough, some of it's there for a damn good reason no matter how ugly it looks.
And when it comes to code, you probably trust devs who have specific insights into issues with code and promising replacements.
At $OLDJOB we used to use nfs extensively, and a common desire was to run some command on the system where the files actually resided
By using $OLDJOB are you saying at every old job you ever held this was the case or just the last one? Because if it's just the last one you should have used
const OLDJOB
Not sure why you used a variable in a comment, maybe because this is hackernews and you want to resonate with other programmers?
In my opinion, the code was very difficult to read and even harder to understand for !expert javascript devs and even for experts.
Is it just me or do "markets" feel like a really dumb AI that is incapable of any sort of strategic planning?
My email looks like ${firstname}@${some-german-word}.jetzt and I never had a problem with German speaking people.
For the "memorable phrase" thing, you may have already figured this out, but I find it's better to generate random passphrases for those. A string of words is a lot easier to say and verify.
Yeah, he asked me for a new one as part of the reset (or just for his further amusement?!) - I just used my brain's PRNG for a few words for that.
It would be tiring and a bit offensive to knowledgeable people, but maybe better then trying to debug the situation.
I have a scheme to give addresses per service, but I do this with gmail on my domain. It goes like $ACCOUNT+$RANDOMLETTERS@$DOMAIN.$TLD
If only. The amount of times people have tried to put mine down as $fistname.$lastname.$tld@gmail.com is genuinely sad.
did I ever say gmail.com >> no, but.. > exactly, so let's try this again (goto 0)
"We have to recalculate weight on airplanes" is just a proxy, a code smell.
Hah. I regularly see patches whose review takes well over 100% the time it would have taken me to create the patch myself.
But then I'm employed by $MEGA_CORP and part of the job description is "helping to build and maintain the OSS community", so helping novices create their first patches is a big part of that.
You need so few subway drivers/conductors that does it really matter if you need one per train?
Taxis are probably average a driver per 1.5 ish customers. Subway/train is hundreds.
This reminds me of optimisation of non critical code. Sure its nice, but the cost/benefit is just not there.
I think that JavaScript and Python, from my experience, certainly increase speed... but that definitely != productivity.
But they could! It's as easy as saying "I can consult on $topic, please contact me to discuss details."
"Log in to see 8 answers on Qu^H^HStack Overflow!"
my bank has a section in their marketing email preferences where you need to check the box IF you don't want to receive any marketing^Hspam email.
If we chew on enough of these lozenges, will our teeth merge into one, curved megatooth?
And why haven't we evolved to have that yet anyway?
Well, in software terms, you're describing a monolithic architecture.
There is also the matter of how evolvable the platform would be. As a species, we're in the process of losing our wisdom teeth, and I suspect that would be harder to do if the skull/jaw/gum/tooth platform was... more tightly coupled, less modular.
Maybe selling a banana taped to a wall could be a way for people to make money, considering one of those sold for ${OUTRAGE}.
But americans do get marketing though. I bet you know about a bunch of companies that were doing $thing in $country before, probably with better outcomes, but never got the recognition.
On the other hand, $OTHER_COUNTRY has a history of $BAD_THING, so the only conscientious thing to do is boycott everything their workers produce too.
However, unlike software engineering, policy shouldn't be made to cover all the corner cases.
s/LTE stack/mmWave stack ?
Seems like the point? Add a bit of bias laund^H^H^H^H^H^H^H^H^H^Hmachine learning and you're good to go!
> HN is a great community
HN feels like white collar GPT-3.
I've been watching a lot of bonsai YouTubers lately. The amazing thing about trees is how much abuse they will tolerate and still figure out some way to grow. You can find videos of somebody pruning all the leaf-bearing branches and half the roots off of a bonsai like it's nothing, fully expecting the tree to recover. Plants have a very flexible instruction set, something like a list of inner if-statements, which bonsai artists understand almost completely and use to dictate their growth. It seems like the default execution of this instruction set looks like "tree" when there are no particular challenges, but the plant would adapt to almost any trauma short of cutting it down to a 1ft high stump... and even then, you will find stumps growing branches.
The difference is between hobbyist agriculture and commercial agriculture. In the latter, consistency, pests and disease become more complex issues to deal with. IMHO there are a lot of analogies to software engineering. Small projects can engage in practices that don't scale, like skipping QA, not adequately testing, inconsistent coding standards.
Today in "GPT-3 ramblings or marketing spiel":
that that kind of language long predated GPT-3. It learned from somewhere :)
I've noticed a recent tendency to compare people's writing to GPT-3 output as a way of saying something like "I didn't understand that" or "I found the style hard to follow".
For some reason this reminds me of the website kuro5hin and how trolling was perfected into a sort of discussion-malware there. With Holocaust denial, it's discussion-malware with a highly targeted purpose: recreating the societal situation where another Holocaust can occur.
> discussion-malware
I've never heard this term and I like it. Relating software-of-mind to actual software can be a powerful intuition pump.
I just hate that Sony can't be bothered to give an explicit send-off to the A-mount line. Coupled with their abysmal customer service reputation, this really makes Sony my textbook example of a faceless, uncaring $BIGCORP.
Sounds like just the next calculated step.
Introduce $badThing with claims about page load performance.
tell sites they need to use $badThing to get into the "carousel"
s/us/your phone, that we control the software for/
In fact, at $work, I developed a very similar architecture and it is running flawlessly for 15 months or so.
Earlier is better to expand something like this to $everything
If I had a mental s/Daily Mail/Reputable Newspaper/g I'd be able to give this article a little more time.
I have nothing nice to say about any Google-owned company but is this really all that different from $city's Best $business or literally any other corporate "award" that's nothing more than thinly-veiled advertising?
This is why you ALWAYS use a Privacy.com (or similar) virtual credit card with limited access to your bank account. It's the same as creating a separation between your API layer and DB layer.
A lot of people who I knew as sympathetic and calm before they took management roles turned into something I could code in one minute: namely a program that asks "how much is this going to take?" and if your answer is above N hours/days then they say "no, we're not doing it".
As in, you're valuable at $COMPANY_X, but you're not challenged to better yourself beyond what you already are. Much of your value to $COMPANY_X derives from skills and knowledge that are specific to $COMPANY_X / $INDUSTRY.
I've got the gift of the gab and so I see this differently. If I had no scruples or morals and chose to drive Uber, I could make an obscene hourly wage simply by picking up elderly people and engaging them in conversation. Most phone scams rely upon preying upon vulnerable, lonely people like this so sadly, it's a public 0 day with no known fix.
The money is there to drive things, pulling it out from one perspective is like looking at one weight in a neural network.
Was this article written with GPT3? It sure reads like it....
> Wikipedia asks for money once a year
if once == "allYearLong" { clapYourHands() }
I don't think that I've opened a Wikipedia page in months, that didn't have a beg header.
I learned somewhere that certain people that pass a certain "threshold" are not only fooled^H^H^H^H^H^Hconvinced by Nigerian prince scams, but utterly convinced that they are true.
Constantly shiny + new ~== a good App Store.
(~== Not necessarily equal to. Did I just invent that?)
Instead of inventing new operators in your sentences, you can also just stick with plain English
As always, "Stop doing $negativebehavior" is less useful than the actual advice:
I can accept that they ran out of cash. It's just like a company running out of servers when traffic spiked.
Sears didn't just "go bankrupt" - it was killed by CEO Eddie Lampert.
s/killed/looted
There's such thing in Russian too. My parents had friends and they would come to our apartment every once in a while. We would call them all "uncle $name"
It's doubtful that any large bureaucracy can execute that decision quickly, though I do agree 3 years is way too long. I'd put 3 months as hard minimum even assuming every internal decision process went as smoothly as possible, and 6 months as a more realistic amount.
This largely has nothing to do with how grievous the transgression is or how sincerely the management wants to do the right thing. It has to do with red tape that is designed from first principles to permit zero exceptions or special cases that can cut through it quickly.
It's like choosing an O(n2) algorithm, baking it in as a load-bearing centerpiece, then being upset something doesn't happen in O(1).
https://notabug.org/ does eat its own Gogs fork^W^W dog food
AT&T's home gateways have a maximum NAT translation table of 1024^H^H^H^H8192 connections.
Last month on HN someone got £7500 from FB, but, everyone thought he should have got more
s/everyone/someone
Note that there are 297 hidden items in that issue so you have to click "Load more..." ceil(297/60) times to read all of the comments
Ben Thompson tried to compare China with over 1.4 billion people with Taiwan with only 24 million people and vehemently arguing that the Taiwan's governance is better is very disingenuous at best. Imagine comparing the governance of large corporation vs. a small startup, it's just different.
I want you to know that any downvotes might have less to do with 2020 or identity politics and more so your sloppy style of conversation. Throwing out a wildly undifferentiated blanket statement and ending on a passive aggressive "cue the downvotes" is bad content in my opinion.
It enjoy being subjected to different views. I hope we can uphold a certain standard for expressing them around here.
Your meta comment is also boring and unoriginal. GPT-3 itself could've generated it
I read somewhere (on HN?) that Italians speak faster than Germans because their words contain less information, so in the end they still communicate the same amount of information per minute. Italians and Germans were used in the example because they were the two extremes.
Is this RISC vs CISC human language philosophy?
We refinanced during the pandemic with $MEGABANK, and they almost exclusively used third parties and email for the entire transaction.
I also called the office number I found at $MEGABANK's website to make sure they'd heard of me.
Beyond that, I had no reason to think $TOTALLY_LEGIT_ESCROW.com was not a phishing front.
At $WORK, we run a lot of 1000s of php servers with 10-20 processes each using nginx.
A 5-story building in China 'walks' to new location (cnn.com)
City refactoring
People intruding the private email? No problem. Politely refuse, and offer private consultancy at $very_high_price, with alternative, to open a bug in the bug tracker, making explicit that there is no commitment.
Watch and listen to pilots as they complete checklists. They point and callout each item, switch setting, etc.
Came here for this.
A: "Passing control"
B: "Taking control"
A: "You have control"
B: "I have control"
This is how I remember it (6174, UH-1Y).
The TCP handshake IRL
Some reporter finds out that $government is doing $bad_thing. They pack up the evidence, rush out the door to talk to their editor. A slick, self-driving car pulls up as they exit the building, they enter and pull away.
> personally never understood why one would pick this over date/hour
Providing a timestamp gives you the same information with higher precision provided you know when now is. I can tell you what day of the week it is, but not what the day of the month it is. Sometimes day of the week even takes extra cycles.
> I am trying to be a good novelist, and hoping that people will forgive me for being a bad correspondent.
%s/novelist/coder
%s/a bad correspondent/unresponsive on slack
Unacademy focuses on test prep and thier anthem while sappy and gung ho, doesn't really have any references to gaming the system. Crack it is in the same vein as Cracking the Coding Interview.
Which is gaming the system, if you ask me.
Cracking coding interviews would be considered "overfitting" in statistical learning parlance.
I own a business. If I was to do a full inventory, I would probably find I'm in the possession of tens of thousands of items. I'm currently in the situation where something breaks daily. It has forced me into being very picky. I no longer buy things, if I can avoid it. Every thing I buy has the potential of being a problem down the line that will require time and attention. Even disposing of broken things can be a big hassle.
This advice applies directly to software. Bring in more dependencies, bring in more custom tooling, and you're bringing in more maintenance burden. There will be bugs. Make sure you really need that shiny new framework.
He wrote an OS project that runs all the infrastructure for your very own dictionary website.
For the confused reader: s/OS/OSS/
Who else has an install base like Amazon in their Alexas and Rings?
a company like Arris that sells DOCSIS3/3.1 cablemodems and GPON end user CPEs to big ISPs like Shaw, Comcast, Charter, Wave/RCN, etc. The main problem with that concept is that if a manufacturer of residential CPEs such as Arris made a unilateral decision to incorporate the tech into their cablemodems and other devices, their $BIGISP customers might not be pleased about it and would buy elsewhere.
Never attribute to malice that which is adequately explained by stupidity"
-Hanlon's razor
Advanced malicious actors often feign incompetence when caught, to take advantage of the naive and forgiving.
This is a basic part of the human OS.
Years ago for my sister's 30th birthday, I did a fun project involving the USPS.
I wanted to send her the message "Happy Belated Thirtieth Birthday!", which is 30 characters, via postcards, one character per postcard.
...
You've reinvented TCP using paper packets.
Because Alibaba, and now Amazon require tracking numbers from sellers.
From time to time they take these tracking numbers, and check them with APIs of shipping companies, and postal services. If a seller has too many invalid tracking numbers, or shipments that don't match the address, they rm -rf him.
If you are at $BigCorp there's probably only a rough correlation between what you are paid and what you are worth.
"Ping me" really threw me for a loop the first time I heard a non-tech say it in an obvious non-tech way. It literally has no other meaning outside of the ICMP echo utility; and the onomatopoeia of hitting glass.
How did it enter the Business world?
Ping comes from submarine sonar - not the networking world.
Writing clearly is like playing Tetris. Sentences should be presented with clauses that drop down and slot together efficiently. At the earliest available opportunity you drop in a block that completes the line and points are won/made.
Don't make your readers hold parts of the sentence in their head. Reorder or split sentences until it can be avoided. In other words, use a really small buffer.
Overflowing that buffer really does feel like a stack overflow, too. Your whole mental state just suddenly disappears in a puff of smoke.
This resplendent sentence in the Vulkan spec did it to me the other day:
The layout of subresources of images on other logical devices that are bound to VkDeviceMemory objects associated with the same underlying memory resources as external memory objects on the lost device becomes VK_IMAGE_LAYOUT_UNDEFINED.
I got about half way through and suddenly discovered I didn't know where I was, what year it was or my name.
That's a lot of qualified noun phrases. This should just be an s-expression. It's already one, honestly, but without the right parenthesis.
(becomes (qualified (layout of subresources of images on other logical devices) (bound . (same-memory-resources (VkDeviceMemory objects) (external memory objects on the lost device)))) VK_IMAGE_LAYOUT_UNDEFINED)
This is how I felt while reading philosophy essays. I'm not even sure half of those are even saying anything.
A lot of philosophy essays are written as part of the writer being in the process of trying to figure things out for themselves, without quite having gotten there yet.
It really shows, just like docs written by someone who hasn't actually understood what they're writing about yet.
I don't know if it's just me, but I very much prefer easy to skim emails to more dense ones. At one point I got weekly project updates from a team I was working with, and one guy wrote dense, short, emails where I would have to read every sentence carefully to get a hang on what was going on. Another guy would write longer, fluffier emails but with bullet points and paragraphs in the same order:
Just by parsing the number of bulletpoints, and the length of each bullet point (and the first word) I would get a surprisingly good grasp on how things were going, and what was hard/complicated (longer bullet point -> more complex), and very easy to read about exactly I wanted to know.
This is how the so called sutras are written: a page of text gets compressed into one short sentence, so you have to stop after each of them and spend an hour unpacking its meaning, but the entire book is often just 200 sentences.
.zip format in history.
Spotify CEO: musicians can no longer release music only "once every 3-4 years" (thefader.com)
"What's he going to record a song about?"
"Nothing."
"Spotify'll kill him."
"I guess they will."
"He must have got mixed up in something with the music industry."
"I guess so," said Nick.
"It's a hell of a thing."
"It's an awful thing," Nick said.
They did not say anything. George reached down for his mobile phone and wiped the screen.
"I wonder what he did?" Nick said.
"Failed to write enough songs fast enough to generate user engagement. That's what Spotify will kill them for."
"I'm going to cancel my Spotify subscription," Nick said.
"Yes," said George. "That's a good thing to do."
"I can't stand to think about him waiting in the recording room and knowing he's going to get it. It's too damned awful."
"Well," said George, "you better not think about it."
(with apologies to Hemingway!)God help me, I can't tell if this is GPT-3 or not.
"This writing looks computer-generated" as a compliment is kind of blowing my mind
Roman numerals by and large were not used for calculating, but for recording calculations. Those calculations were done (as the very word "calculate" suggests) using pebbles or other tokens, on some kind of counting board.
The point of Roman numerals is to be as direct as possible a representation of the state of the counting board. They are a serialization format.
Think of it as the JSON (or s-expressions if you like) of the ancient world. You don't run your algorithm by writing and rewriting JSON literals over and over with pen and paper. They are just a record; your computation is done using a different automatic tool.
Many people assume their manager knows what the employee is doing. They often aren't, meaning they go by what they can see, which is lines of code. The smart thing to do is to regularly keep your manager updated on what you're doing, especially if they don't come by regularly and ask you.
Rather than an integer number of lines of code, how about using a boolean : "it works" or "it does not work"?
Not everyone has good managers.
$JOB-2, admittedly about 4 years ago now, the good manager with a background in software left for a better opportunity and was replaced by someone who's background was management.
My grandfather used to sit with me for an hour every morning and used to teach me maths.
He would focus on basics first. He would make sure I had the basics drilled in to me. Not just understood them, but mastered them. Then we would move on to the next topic.
It was a bit slow at first. But after a while, once the basics were done, I finished the whole year's math book in 2-3 months.
Drilling basics is basically like having the basics in O(1) look up with very reduced space complexity too. It reduces the amount of overhead your brain utilises.
This reminds me of a story I once heard about shipbuilding during WW2. Supposedly, although designs and blueprints were made in great detail, following them today wouldn't give working ships, because the workers implementing them at the time saw where the designs wouldn't work and fixed them of their own initiative.
In a way, the opposite of today's optimizing compilers.
I have a heuristic. A 'code smell' for social science articles,
Why do you think this is specifically a 'western society' thing? Browse Japanese sites and online tools and there is just as much gamification and 'thrilling' graphics and animation - if not more. Github looks like a technical white-paper in comparison.
Modern Japanese culture is considered to be part of "western society", for better or worse.
The converse statement is something like "Japan is not an eastern society" which just sounds... laughably incorrect.
Of course it sounds ridiculous. Boolean algebra says the validity of a statement's converse is independent of the original. P → Q, tells us little about Q → P.
I love a good font (and try to use one on my own blog), but part of me gets really giddy when I discover a site with very little styling. It's like I've found some secret oasis that's going to have a high signal-to-noise ratio, or at least some more "raw" writing than you'd find on ${popularNewsWebsite}.
Remote work has its perks, until you want a promotion (wired.com)
Humans don't have emotional object permanence.
A perhaps more techie way of thinking of it is our relationships are in a mostly-LRU cache. The people we have interacted with most recently are the ones that matter most to us. If you aren't regularly resetting your place within that cache, you get bumped.
The LRU cache analogy might be one of the best comments i have ever read.
We probably wouldn't hesitate to say "I don't believe $NONHUMAN_ANIMAL parents love their children, and vice-versa...." about most animals.
Blogging Is Not Dead (garron.blog)
"X is alive / X is dead" is binary thinking and taking sides on this is pointless and divisive. Better to use a float rather than a boolean to model how popular something is.
What surprised me most is that he presented himself as the biographer of James Bond, as if he were real. I wasn't aware of that history.
It's a writer's technique somewhat similar to method actors who take on the character's persona as their own for the duration of a play or filming. Pretty much as far from "kill your darlings" as one can get, tbh.
Forking your own thinking process to have a secondary personality execute in parallel sounds as close to "killing your darlings" as possible, given that personality would presumably have their own favorite expressions and tropes.
Interesting: whoever edited that article miscorrected "cobble" to the likely more familiar but incorrect "cobblestone".
I've seen a huge increase in such errors over the past decade, both in terms and tense. I don't know how to explain it but it is discouraging. Sometimes the errors are quite confusing until you realize what happened; this one is quite minor.
In Minecraft "cobble" is certainly understood to be short for cobblestone. A "cobblegen" is either an arrangement of materials (lava, water, something heat resistant) so as to cause the game to make and replace cobblestone blocks when you mine them out, so as to obtain unlimited amounts of this building material, or in modded Minecraft it's a more compact machine which makes this material, perhaps in very large quantities indeed, and maybe related materials like sand.
Hey, just a head's up, I was reading your blog and noticed a typo: s/formally/formerly/
eg. go watch a SGM play 30 second hyperbullet chess, I don't think I have either the memory or raw processing speed to do what they do, ever. If those guys exist a lot of other people have way higher ceilings. Also realize that chess (and by extension must be a lot of other activities) rely on both a crazy cpu, an amazing memory and an insanely built-out internal database of positions and ideas, and since my cpu is good but not unbelievable, my memory is nothing special and my time is limited there must be a lot of activities I'll never really be good at. Also just getting older and staying unsuccessful relative to your ego, you just start to compromise I think.
My response to picking up a number is to answer the call and say nothing. Auto-dial systems will route the call to a person when they get a "live" response. I don't know the criteria but I'm pretty sure it's them detecting noise on the call (which could be voicemail).
A human calling will wonder what is happening and fill the silence by saying something. A machine will not.
I've encountered robots in the last 6 months that have started with "Hello?" when I didn't say anthing. It tripped up my Turing Test at first, but eventually hit an ALICEBot-like moment that crashed the whole thing down.
Real wages haven't increased since 1970.
We only feel richer because:
* Most households have two wage earners now.
* We use lines of credit to borrow for discretionary purchases, we lease cars, pay by subscription for things more.
* We have more gadgets. (Note that this has been proven to make people any happier.)
> Note that this has been proven to make people any happier.
s/Note/Not/? Or are you missing a "not" somewhere else?
In my former life as a consultant I came to very much dislike personas as implemented by ux designers.
Personas are a magnet for prejudice: they are based on the idea that clusters of people all behave the same (old people, young people, professionals, stay-at-home mothers, what have you).
Yes, the very idea that customers can be bucketed is flawed. We are all unique people.
I think GP is fine with bucketing, but they're saying that f(age, gender, interests, ...) is not a good hashing function.
Is it possible that people simply continue to think about what they were trying to learn, consciously or not, when given no tasks? Why is the control comparing people who tried to learn information and then took a break to people who tried to learn even more information? Would a more insightful control be to look at how people who took a break compared to people who continued studying the material during the break time?
I agree with you entirely. I want to make a few points though. First is that even when I am actively listening to someone speaking, my brain will make associations with the new information (coming from my auditory sensory registers), so I context-switch involuntarily every second. Think of process preemption.
Roughly like this:
t0: hear the word "dog"; my auditory registers record it t1: my brain processes the word "dog"; I imagine what "dog" looks like hear the word "cat" concurrently, goes into registers t2: my brain processes the word "cat" I imagine what "cat" looks like hear the word "lamb" concurrently, goes into registers
I've timed it in actual play: it's quicker to google for a monster stat block (one from the SRD, obviously) than it is to look it up in the Monster Manual sitting right next to the laptop.
Sure, but from experience in play, sticky notes in the Monster Manual are much faster for switching back and forth than browser tabs are.
That's a cache, though, when the use case at hand is random access.
Brain is very active when you sleep, a lot is happening. Imagine sleep is just a mutex on big set of data on which computation needs to be made, compression, data reorganization, index optimizing. Data that you received that day is segregated , decisions are made which data to keep and which to delete. After that lock is freed and you wake up. If you don't sleep your system will run slower and slower over time and will timeout more and more queries until it will start to return corrupted data. You need to sleep to keep the system healthy.
tl;dr: It's not because the cardboard boxes are significantly better than cribs and other sleeping methods, it's the fact that the box comes with almost everything a new parent needs to look after kids, which means they don't have to shell out $foo-money to be able to take care of the children properly, and aren't left worried that they left something out.
English pronunciation <-> writing is so far from a mapping, it causes a lot of resource waste.
Even if there are dialects that pronounce the same word differently, you could still find a lot of common ground.
Finding that common ground would mean switching from our current system of somewhat-arbitrary spelling to a different but very similar system of mostly-arbitrary spelling. It imposes the same memorization burden on everyone and the benefit is slightly more predictable pronunciation within each of a set of officially-blessed dialects. That ground gets lost over time regardless; there is a reason predictable pronunciation is a feature of spelling systems that either (1) are new, or (2) have just undergone reform.
If your biggest problem lies in a circumstance you rarely encounter, arguably fixing it is not a priority.
> for example I always mess up the words study and student, it's infuriating
This is a funny example to use, since it fully conforms to the rules I described above — study uses the STRUT vowel, and student uses the GOOSE vowel. It would be a better example for the complaint that we have more sounds than symbols.
Good points, but I disagree. Decoding and encoding becomes a lot harder, if vowels change depending on consonants coming after them, or something else even further down the line. (I'm not a linguist.)
It's like a config file specification that supports gotos.
Because there's a bit of a feedback loop with success. If others see you as being successful or impressive (on whatever axis they care about), this attracts them to you, and having a more admirers increases your social power and influence, which gives you more opportunities and better chances of success in your future efforts.
This also explains [redacted]'s formula for career success, which is basically:
10 Make something awesome
20 Tell people about it
30 GOTO 10
English suffers from the same problem as UNIX: they're both good enough.
Or you know, just look away from the monitor, in the physical space of your office/whatever instead of a flat surface, which would have similar benefits.
So many office spaces are rectilinear and planar. I find the fractal real world to be so much more restful to look at. It refreshes my mind in a way unlike any manufactured surface.
There are few things in life more important than choosing one's peer group well. The Internet gives you many more options than we had available prior to the existence of it. Choose wisely and re-evaluate that choice periodically to see whether your peer group continues to represent your goals and values.
Why? Your peer group literally gets arbitrary code execution on your brain. (It's a flaw in MonkeyBrainOS 1.01 which we haven't patched yet.)
It's common amoung US companies as well. How many tech companies aren't available in !USA? How much "streaming TV shows" aren't available in !USA?
Walking Through a Doorway Makes You Forget (2011) (scientificamerican.com)
Not entirely unlike running a garbage collection cycle (or freeing a pool) after each HTTP request...
Great read. Somewhat of an off-topic question, but here goes:
> Watkins wanted her pen name to be spelled in lowercase to shift the attention from her identity to her ideas.
I'm sure what I'm about to say has been discussed before — but wouldn't this accomplish the opposite effect? I feel her "unconventional" name makes me focus more on it, not less (especially when her name is used at the beginning of a sentence, where we are trained to expect a capital letter no matter what). Do other people with lowercase names have similar justifications?
To me it's a small pattern breaking annoyance, like a linter warning I can't turn off that triggers every time I see it.
Mobile app stores handle a lot of hassle like distribution and billing. I would avoid complex backend at all cost if you don't want to be on 24/7 devops duty. Maybe periodically updated CVS at basic webhosting would be enough.
s/CVS/CSV/
Slight note about Dan Wang picking 2005: That was the peak of CS degrees awarded because it's 4/5 years after the height of the dot-com bubble. So the upward bump in the mid-2000's is somewhat explainable as an anomaly.
Re: the choice of 2005 as origin, if you rebase on 2009, then CS degree growth looks on par with other STEM fields.
.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>As you know, functions can accept arguments positionally:
>>> def example(a, b, c):
... print(f'a={a}, b={b}, c={c}')
...
>>> example(4, 'hello', [0])
a=4, b=hello, c=[0]
or by name (aka keyword arguments):
>>> example(c=[0], a=4, b='hello')
a=4, b=hello, c=[0]
or both, as long as all the keyword arguments come after all the positional arguments:
>>> example(4, c=[0], b='hello')
a=4, b=hello, c=[0]
It would be nice if we could have a function which can accept any number of arguments. For example, a function that adds multiple numbers at once:
>>> add(1, 2)
3
>>> add(10, 8, 12)
30
You could achieve this by giving the function a single parameter, an iterable. Then you can just pass in a list of whatever length you need:
>>> def add(numbers):
... total = 0
... for number in numbers:
... total += number
... return total
...
>>> add([1, 2])
3
>>> add([10, 8, 12])
30
But this is Python we're talking about, so surely there's a better solu—
Right, a better solution. Python offers:
argument packing: providing additional arguments into a function call, where they will be packed into a data structure.
argument unpacking: providing a data structure into a function call, where the elements will be unpacked to fulfill the parameters.
With positional packing, we can pass as many positional arguments as we want into the function, and they will be packed into a tuple under a single name:
>>> def example(*args):
... print(args)
...
>>> example(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
The asterisk on *args
indicates that args
is the packing parameter. In this context, Ruby refers to that asterisk as the "splat" operator, or you can just call it "star".
There is not very much magic going on here, it's just a regular tuple:
>>> def example(*args):
... print(args)
... print(type(args))
... print(len(args))
...
>>> example(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
<class 'tuple'>
5
We can use this to write our addition function:
>>> def add(*numbers):
... total = 0
... for number in numbers:
... total += number
... return total
...
>>> add(1, 2)
3
>>> add(10, 8, 12)
30
Notice that the star is not part of the variable's name. You don't call it *numbers
during the body of the function, only in the header.
Star-args must come after all of the other positional parameters in the definition:
>>> def example(a, b, *c):
... print(f'a={a}, b={b}, c={c}')
...
>>> example(1, 2, 3, 4, 5)
a=1, b=2, c=(3, 4, 5)
>>> class Scalar:
... def __init__(self, value):
... self.value = value
... def scale(self, *numbers):
... return [self.value * x for x in numbers]
...
>>> Scalar(2).scale(4, 5, 6)
[8, 10, 12]
If you place any more parameters after star-args, they must be passed in by name (because if you tried to pass them in positionally, they would get lumped into the star-args):
>>> def example(a, b, *c, d):
... print(f'a={a}, b={b}, c={c}, d={d}')
...
>>> example(1, 2, 3, 4, 5, d=6)
a=1, b=2, c=(3, 4, 5), d=6
>>> def scale(*numbers, scalar):
... return [scalar * x for x in numbers]
...
>>> scale(1, 2, 3, scalar=8)
[8, 16, 24]
With positional unpacking, we can use the elements of an iterable as the arguments of a function call:
>>> def example(a, b, c):
... print(f'a={a}, b={b}, c={c}')
...
>>> my_args = [1, 2, 3]
>>> example(*my_args)
a=1, b=2, c=3
>>> example(*[1, 2, 3])
a=1, b=2, c=3
>>> example(*range(1, 4))
a=1, b=2, c=3
>>> def double_sides(width, height):
... return (width * 2, height * 2)
...
>>> a = double_sides(3, 4)
>>> a
(6, 8)
>>> a = double_sides(*a)
>>> a
(12, 16)
You can pass arguments in normally on either side:
>>> example(1, *[2, 3])
a=1, b=2, c=3
>>> example(*[1, 2], 3)
a=1, b=2, c=3
If the iterable is not long enough, you can also specify the rest by name:
>>> example(*[1, 2], c=3)
a=1, b=2, c=3
If the iterable is too long, you will of course get a TypeError for passing in too many arguments. But if the function has a star-args, what do you think will happen?
>>> def example(a, b, *c):
... print(f'a={a}, b={b}, c={c}')
...
>>> example(*[1, 2, 3, 4, 5, 6])
a=1, b=2, c=(3, 4, 5, 6)
Did you know that the splat operator can take the elements of a nested list and make them elements of the parent list?
>>> [1, *[2, 3]]
[1, 2, 3]
Therefore:
>>> def example(a, b, c, d):
... print(f'a={a}, b={b}, c={c}, d={d}')
...
>>> example(*[*[1, 2], *[3, 4]])
a=1, b=2, c=3, d=4
(I'm not saying you should actually do this)
With keyword packing, we can pass as many keyword arguments as we want into the function, and they will be placed into a dictionary with the argument names as strings. We use two stars for this:
>>> def example(**kwargs):
... print(kwargs)
...
>>> example(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
Star-star-kwargs must come after all the other named arguments in the definition. The kwargs dict will only be used for arguments that aren't explicitly defined:
>>> def example(a, b, **kwargs):
... print(f'a={a}, b={b}, kwargs={kwargs}')
...
>>> example(a=1, b=2, c=3)
a=1, b=2, kwargs={'c': 3}
In Argument Forwarding I will show the most common usage of kwargs. Until then, there are not very many situations where I use it. I guess you could have a "secret menu" of arguments that are supported but not shown in the function's parameter list:
>>> def unassuming_storefront(**order):
... if 'wink_wink_nudge_nudge' in order:
... print('Say no more')
...
>>> unassuming_storefront(wink_wink_nudge_nudge=True)
Say no more
With keyword unpacking, we can use the (key, value) pairs of a dictionary as the arguments of a function call:
>>> def example(a, b):
... print(f'a={a}, b={b}')
...
>>> my_args = {'a': 1, 'b': 2}
>>> example(**my_args)
a=1, b=2
And if the function also has a kwargs?
>>> def example(a, b, **kwargs):
... print(f'a={a}, b={b}, kwargs={kwargs}')
...
>>> example(**{'a': 1, 'b': 2, 'c': 3, 'd': 4})
a=1, b=2, kwargs={'c': 3, 'd': 4}
Once again, I don't typically use this feature on its own, and I'm assuming you understand how this works by now. So let's move on to the most common usage for *args
and **kwargs
.
Consider an API wrapper which makes web requests. Behind the scenes there is probably a request
function:
def request(url):
# does some Internet magic.
def get_comments(user):
url = f'https://example.com/user/{user}/comments.json'
return request(url)
def get_submissions(user):
url = f'https://example.com/user/{user}/submissions.json'
return request(url)
One day we decide to add a new argument on the core request
function. Suppose we want to give our requests a timeout:
def request(url, timeout=None):
# does some Internet magic.
def get_comments(user):
url = f'https://example.com/user/{user}/comments.json'
return request(url)
def get_submissions(user):
url = f'https://example.com/user/{user}/submissions.json'
return request(url)
Of course, when people use our API wrapper, they don't call request
directly, they call the other functions. So in order to use the new timeout feature, we'll have to add a timeout
parameter to all the functions which call request
so they can pass it along:
def request(url, timeout=None):
# does some Internet magic.
def get_comments(user, timeout=None):
url = f'https://example.com/user/{user}/comments.json'
return request(url, timeout=timeout)
def get_submissions(user, timeout=None):
url = f'https://example.com/user/{user}/submissions.json'
return request(url, timeout=timeout)
Great, now every time we add a new parameter to request
we have to go copy-paste it to every other function in the entire library. Not to mention it seriously clutters up all the function definitions and may distract you from the important parameters those functions have.
It works, but it ain't cool. And why would I want to do anything that's not cool?
Instead, let's take advantage of args and kwargs:
def request(url, timeout=None):
# does some Internet magic.
def get_comments(user, *request_args, **request_kwargs):
url = f'https://example.com/user/{user}/comments.json'
return request(url, *request_args, **request_kwargs)
def get_submissions(user, *request_args, **request_kwargs):
url = f'https://example.com/user/{user}/submissions.json'
return request(url, *request_args, **request_kwargs)
In this case, the end result is a little longer. But now, no matter how many new positional or keyword parameters we add to request
, we don't have to touch the other functions ever again. Any arguments that aren't part of their own definition will simply be forwarded along to request
.
If request
uses any other internal functions behind the scenes (probably urllib
), it might even forward some arguments there.
Argument forwarding is a staple of writing decorators. The wrapped function needs to support all of the args and kwargs of the original function without even knowing what they are!
import functools
import time
def timed(function):
@functools.wraps(function)
def wrapped(*args, **kwargs):
start = time.time()
return_value = function(*args, **kwargs)
end = time.time()
elapsed = end - start
print(function, 'took %s' % elapsed)
return return_value
return wrapped
>>> import hashlib
>>> @timed
... def hash_it(data):
... return hashlib.sha256(data).hexdigest()
...
>>> hash_it(b'hello')
<function hash_it at 0x04BF58E8> took 0.0005013942718505859
'2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
It's also very useful for object inheritance, where the child class has some specific parameters and the rest of them get used in the super constructor:
class DatabaseObject:
def __init__(self, db_connection):
self.connection = db_connection
class User(DatabaseObject):
def __init__(self, username, *args, **kwargs):
super().__init__(*args, **kwargs)
self.username = username
>>> u = User(db_connection='just pretend!', username='exampleman')
>>> u.username
'exampleman'
>>> u.connection
'just pretend!'
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Over the past two years I have become aware of what I now feel is the most important element of habit formation: friction. Recognizing friction has helped me to understand my current habits and form new ones.
I think that all habits can essentially be boiled down into two ingredients:
More potently, I think we can expect that we will always pick the action which has the best ratio of value/friction
.
Take homework for example. You're supposed to be doing homework, but getting distracted on the internet is sooo tempting. Let's make a chart:
Sure, homework is important. It gives you value in the form of a grade which is important to the rest of your schooling. It's certainly much more important than lazily scrolling the internet. But boy does it have a lot of friction. Maybe it's boring and difficult. Maybe it's math homework with 50 of the same kind of problem that you're sick of doing. Maybe it's an essay on a topic you don't care about and you can't think of anything to write. Procrastinating on the other hand is easy, and in the age of notifications the internet is more than willing to come to you. The ratio of value/friction
leans heavily in favor of the internet. I for one have always been a procrastinator.
As the deadline approaches, the homework starts to gain more value — on top of the grade you have "avoiding the shame of not turning anything in", "avoiding the embarrassment of being called on in class and not having an answer", "avoiding a slippery slope trend of not doing my work". If these are enough, the homework will finally get the better ratio and you'll do it. If they're not, well... I assume we've all skipped assignments before. Students who regularly skip homework either aren't finding it to be valuable enough or have too many alternatives with lower friction (or have extenuating circumstances at home, I apologize if that's the case).
So what to do? Clearly I believe that the value of a task can change, but in my experience I don't have much control over it. Short of realizing some benefit that I genuinely didn't know was there, I find value to be generally outside of my control and impossible to give actionable advice for. Just, like, think about how important it is. Just tell yourself to do it. Great thanks. That leaves the other variable: friction.
If you want to build a habit, you should reduce the friction of that habit or increase the friction of the alternatives.
To continue the homework example, you can increase the friction of internet distractions by putting your cell phone or computer physically far away from you, or study in a room that's far from them — make it so that in order to look at your phone you would have to intentionally get up and do so. At any rate this will certainly stop notifications from stealing you. If your homework requires the computer, try disabling wifi after loading up any webpages that you absolutely need.
Decreasing the friction of homework is not always easy. Try splitting the assignment into multiple parts so that no individual part feels so daunting. For an essay, separate gathering sources, writing your outline, and filling in the body, for example. Anyway I tend to find that once I'm working I'm more willing to continue, so the only thing that matters is reducing the perceived friction at the very beginning.
I'm not in school any more, but when I had essays to write I got into the habit of loading up MS Word, writing my name on the page, and leaving it on my taskbar. It would remain otherwise blank for another two or three days in some cases, but it made me feel happy that I had at least "started", provided a constant reminder to work on it, and reduced the friction of switching into work mode down to a single click. Check out Will Schoder's video The Closure Effect about the Zeigarnik Effect / open loops / closure. Will's channel is great and I encourage you to watch the rest of it. After you do your homework.
Sorry for talking about homework so much. I think it demonstrates my point in a way that we've all experienced regardless of age or expertise. But make no mistake — I think we can apply this to everything:
Brushing your teeth prevents you from losing them, and only takes a few minutes out of your day.
Eating healthy is ideal, but unhealthy foods are numerous, cheap [1], and tasty [2].
Those of you who drink coffee have probably reduced the friction for yourself by setting up automatic morning brews or writing terminal programs to start the machine at a distance. Some people use Keurig-style machines at home, and I think the plastic waste is higher than necessary, but clearly they bring the friction way down.
Programmers know that writing documentation tends to be low on the priority list. Conveniently, just today there were several posts on hackernews about writing documentation in Markdown (one, two, three). Some argue that other formats like AsciiDoc or rst are more powerful (higher value), which is hard to deny, but clearly the value/friction
of Markdown has yet to be defeated.
Starting an exercise routine when you don't currently have one is hard. I know because I don't currently have one. I think that most people, once they get themselves to start, find that the value is higher than they expected (beyond fitness, there's sleep quality, stress relief, better appetite) and the friction is lower than they expected (being a little sore isn't the end of the world, you only need to spend a few minutes each day). Probably my biggest source of friction in starting to exercise is confronting the current state of my fitness. As long as I simply don't try, I can imagine my abilities to be as high as I want.
I encourage you to examine the habits in your life, especially the ones you want to get rid of and the ones you want to form. Ask yourself about the value they provide to you, and the sources of friction. Understand that the brain will want to do the things with the fewest steps, the smallest distance, the least lifting.
[1] Meal prepping, buying enough ingredients to make many meals, can bring the per-meal cost down. A singular search found me this Harvard article suggesting that it's still $1.50/day ≈ $45/month more expensive. I imagine this has an air of Vimes's boots to it especially for e.g. overworked single parents, however.
[2] I typically hear healthy eaters say that junk food tastes bad to them now. That helps if you're already there! Trusting this can give you confidence (thus value), but taste is undoubtedly a source of friction.
Class is dismissed, you're free to go, but this last portion is for how I have identified value/friction
in my own life.
I've never liked using planners or calendars. Partly because having to get a physical thing out of my backpack, and flip to today's date, and not remembering my tasks any time I didn't have it with me was too much burden. And partly because there are some tasks that don't need to have a dated deadline, like finding some movie I heard about and want to watch. During college I started using checklists on my phone [3]. Prior to that I rarely used any written tasks and just remembered everything. I've got one list for things that have due dates, ordered by soonest due first, and another list for things without due dates, ordered by most-recently-created first since those ideas will be freshest in my mind and easiest to start. Of course, that list continues to grow faster than I clear it, but scrolling through completed tasks shows I've done quite a lot. Adding emoji helps visually categorize tasks. Meanwhile, there are people who enjoy writing on physical journals so much that that's the better habit for them.
I have been using Anki to keep up on Korean vocabulary for about one year now. I've learned that the best time to do my cards is immediately after I wake up, while I'm still in bed. Not only are my scores highest at this time, but I'm most likely to get the whole day's cards done in a single session. There is no 'second best' time of day to do my cards — if I don't do it in the morning in bed, it's a crapshoot as to when I'll get around to them during the day, usually it takes multiple small sessions, sometimes I don't finish until 1 AM, sometimes I don't finish at all and do extra the next day. I only do about 30 minutes each day so it's not even a big undertaking, but once I'm out of bed I've got too many distractions and friction to get around to Anki.
Learning Korean requires spending a lot of time listening to it. Certainly the long-term value of learning the language is very high for me, but on a day-to-day basis the value of any individual listening session is hard to measure. I can't feel my improvement on such a short timescale, so individual listenings are unfortunately of somewhat low value. Thus it's necessary to reduce my friction as much as possible. That means keeping the tracks on my phone, using Musicolet which gives me a queue (not playlist!) dedicated to Korean, and putting the Musicolet widget on my home screen so I've got a play button right there. I mentioned this in Are children better at learning languages. My current source of friction is earbuds, I wish I could just have it beamed into my brain with no mortal coils to speak of. Those true-wireless bluetooth earbuds seem promising but then you've got the friction of charging them and my experience with bluetooth sound quality hasn't been great, though that might just be from low-quality devices. It would also be nice if Musicolet had widgets for playing particular queues, because the widget now only shows the current queue and you have to open the app to switch them. The next time I get a new phone I think I'll keep this one as a dedicated Korean device with 24/7 airplane mode to save battery and a play button right on the lock screen.
I wrote gitcheckup.py to check the number of changed files and unpushed commits in each of my important git repositories. The cwd doesn't matter, it always shows me a complete list. I have a tendency to make small or experimental changes that I forget about and go unpushed for a long time. gitcheckup helps me keep my repositories in a clean state by showing me empty checkboxes (the horror!) next to what needs attention [4].
I have a digitizer / drawing tablet that I like to use as a mouse even when I'm not doing any graphics work. It's fun to use and helps me prevent wrist strain from using a regular mouse too long. But when using the tablet, accurately double-clicking is a little harder, and switching from clicking to typing requires dropping the pen in its holder, so there is a bit more friction to using the tablet as a mouse replacement and I'll often instinctively reach for the regular mouse instead. So, I'll occasionally toss my regular mouse to the other side of my desk as a way of forcing the use of the tablet.
[3] Originally I was using the built-in tasks app on my phone which is an LG, but it didn't sync with my computer. Currently I'm using Microsoft's To Do. I am relegating this to a footnote instead of inlining it because I don't actually think it's the greatest option in this space and it lacks many features I want. Like you can print, physically-on-paper print a list but can't export it to json or anything. I just picked it because it's free without ads or premium, isn't totally terrible, and isn't Google, criteria which I find difficult to satisfy on Android. It's made by MS though which isn't great either. Sorry for rambling, I'm battling between my feelings that I should share my current solutions in this article versus my disdain for advertising especially a non-open application by MS.
[4] This is a good example of tasks that don't go on my regular checklist — it's too dynamic and would be too prone to falling out of sync. I strongly believe in letting the current state of the filesystem act as its own 'checklist' so long as you remove the friction of querying it, that is by writing scripts when necessary. Same goes for my downloads folder, which is perpetually non-empty but I don't need to write "organize downloads" on my checklist because the downloads folder is already it's own checklist — what's there needs to be organized and what's not doesn't. Occasionally I will add a "[tag]" to a filename that needs later re-processing so that by searching my disk with Voidtools Everything, poof, there's a checklist.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>https://en.wikipedia.org/wiki/Betteridge's_law_of_headlines
People who learn a new language as a teenager or adult know that it's a very long and difficult process. There comes a time in every language learner's life where they wonder why learning their native language as a child seems to have been comparatively very easy.
There is a popular notionww that the reason we can learn our native language so well is because childrens' brains are more plastic — pliable, moldable, teachable. While I'm not opposed to believing that children have some level of biological advantage, I think this argument is overblown and serves to be a conversation-stopper more than anything else.
I am not a linguist nor a neuroscientist nor a psychologist. I didn't read any studies before writing this article and don't have any sources to cite. Sorry. The purpose of this article is not to definitively answer the question but to exercise critical thinking in the face of Claims From The Internet. I want to come up with actionable takeaways instead of just rolling over. I am a layman on this topic and so are you [1]. Even if I had read some neuroscience journal papers, I've heard too much about the flakiness and irreproducibility of psychological studies that I wouldn't actually feel any more confident. I would probably just cite what sounds right to me and ignore the rest. Purists will be annoyed that I can admit this and continue writing anyway. Such is the nature of understanding topics beyond my own expertise.
[1] probably
Oh look, it's another explanation of Occam's razor on the internet. Trust me, I wish I didn't have to do this, but there are too many peopleww who think Occam's razor means "the simplest explanation is probably correct". Even Contact gets it wrong, and, as far as I can tell, everything else in that movie is scientifically accurate.
The problem is in the word "simple". If the question is "how do birds fly?" then we could very simply answer it with "magic". In fact, this simple answer could cover just about anything we don't understand. But it's not correct.
A better phrasing of Occam's razor is "one should prefer the explanation that makes the fewest assumptions". To say that birds fly with magic is to make many assumptions: that magic exists, that birds have magic and we don't, but we were able to put that magic into airplanes...?. I also choose the word "prefer" because there's no need to smugly pat myself on the back for picking what's "probably correct" when the whole point is to objectively recognize what I know and don't.
When the question is "why is language learning easy for children but hard for adults", then the answer of neuroplasticity starts to sound like magic, and there is not much in the way of quantifying the difference between child and adult neuroplasticity. The difference is just enough to explain away the question [2], but not too much or else adults would be totally incapable of learning anything at all.
Remember, this article is written by a layman using critical thinking to evaluate what I've heard. As such, the remainder of this article lists advantages that children have over adults and vice-versa without resorting to such assumptions.
[2] I still haven't cited anything
Learning your first language is pretty much sink or swim, just without the threat of watery death usually associated with sinking and swimming. You've got to admit there's an element of pressure for children to learn a first language. How else will they ask for cookies?
When I am reading or listening to something in Korean and I get frustrated or bored because I don't understand it, I can just turn it off and go do something else in English. There is very little external pressure for me to persevere. Even in foreign language classes, where some teachers strive for 100% target language in the class at all times, of course peers will use English amongst each other. Children don't really have those kinds of alternatives. They only other form of communication they have is crying.
Babies got nothing to do. No work, no school, no obligations whatsoever. If I could sit around listening to my target language all day I'd progress a lot faster too.
An adult learner first has to subtract sleep and responsibilities from their daily allotted 24 hours, then with the remainder has to decide whether learning a language is really important enough to give that time up. Especially because spending X hours on something we're bad at is tougher to do than spending the same X hours on something we're already good at.
It's also important to realize that language is ultimately nothing more than a tool for communication. It's fun to romanticize the idea of learning an interesting language, but that's like romanticizing the idea of building an interesting hammer, which isn't of much use if you don't have anything to nail down. I read this comment recently and it stuck with me:
Whenever I hear a native English speaker idly thinking of learning a language for "business reasons," this is the comparison I draw in my head ... it subtly hints at the reality: even with your hard-won language ability, you'll still need to pair it with another skill[set] to get the job. At minimum something like marketing, editing, or translating. No one will pay you to just speak the language.
/u/xanthic_strath on How useful is Mandarin if you aren't Chinese?
Do you really want to dump hundreds or thousands of your limited life hours into learning the foreign language, only to reach 'competence', when you could be developing your other skills into mastery? You still have to have everything else that makes the language worth using. It's a hard sell.
My desire to learn Korean is purely interest-based, because I enjoy it, so I'm not worried about this part personally. I recognize that the situation is different for people learning English which might be the only means of getting into a career field they want to pursue.
From the moment a child is born, it's surrounded by a group of people who
This group is often known as the "family" or so I hear.
Compare that with adult learners who
MotivateKorean [4] often said that when you're learning vocabulary, there is an important moment where you "make it yours". Discovering an opportunity to use a new word, and succesfully using it, and hearing it come out of your own mouth contributes much more to your learning than just doing flashcards. For children this will occur naturally and frequently in their daily life. For adults, especially those learning on their own in their home country, it won't.
[3] You've probably seen Stephen Krashen demonstrate comprehensible input. It's a good lesson, for sure, but in practicality it's extremely difficult to find material that matches your i+1
. Partly because it's hard to define your current i
in the first place. The parent-child relationship excels at this in a way that a language teacher or tutor or internet material simply can not. My advice is to not worry about i+1
too too much. I have been listening to TTMIK's Iyagi since nearly the beginning, and although it is still above my skill level, I can feel that my comprehension has been going up. Don't get stuck in an endless search for the perfect i+1
material, just find something that isn't impossible and get started.
[4] The channel still exists but he has removed videos of himself and handed the channel over to someone else.
I was going to make a separate header for "not expected to output for a long time" but let's just combine those thoughts here. When an adult starts learning a language, they'd like to start using it sooner rather than later. Even those who emphasize input-before-output like Matt vs. Japan [5] understand that adult learners don't want to, and in fact shouldn't, refrain from talking for two years like children do. Children have the advantage that nobody expects them to say anything for a long time; they get to sit back and soak it up first.
When an adult learner starts texting or talking in their new language, they'd prefer to not make mistakes. Some are more embarrassed about mistakes than others, but I think it's true for all of us. I for one would rather forgo a thought than blunder it.
Of course, mistakes can be very productive because you can get feedback instantly and in context which are pretty much the two best things for feedback to be. It's just very difficult to overcome the pride. See also the previous point about how nobody wants to listen to you stumbling all the time and suddenly I'm even more self-conscious about opening my mouth.
[5] he probably would prefer that I link to massimmersionapproach.com first and foremost, but truthfully his youtube channel is a better resource than the site at the moment
The whole premise of this article is an adult trying to figure out why learning a new language is so hard when learning their native language was so easy. So to that end it's important to remember that you had mandatory English classes every single year for, like, twelve years. So when your math classes progressed from arithmetic > algebra > geometry > trig > calculus, and your science classes progressed from biology > chemistry > physics, all the while there was English > English > English > English > English. Literacy rates haven't always been as high as they are now. Children learning to read and write is in fact a big undertaking and not as trivial as it seems in our distant memories.
Just take a look at the vocabulary and expressiveness of a ten year old and remind yourself that that is what ten solid years of uninterrupted native exposure results in. If you can beat that level of comprehension and expressiveness in your foreign language in under ten years (I bet you can), then you're beating the pace you set by learning your native language. I'm currently at 1.5 years of my leisurely pace of Korean studying and I can mostly comprehend teen level text as long as I'm allowed to use a dictionary (listening comp is a different story, but anyway). I know that if I had studied harder over this past year and a half I'd be a lot better, too.
I want to restate this point: It seems to me that learning the second language is not actually harder than the first. We just didn't feel and/or don't remember how hard it was and how much help we had the first time around.
Brady: You feel so omnipotent when you're with little kids, and you understand things so much better. And we adults are like these gods, and they're trying to understand nuance that they can't possibly understand and you occasionally have these waves of emotions where you're like "I just know so much more than you. I can impart so much knowledge on to you and you don't understand this but I do".
Brady: Like a kid'll go near a lake or something, and you'll be like "don't go near the lake" and you'll stop them from going in the lake. But you know so much more about why that is. You know about drowning and oxygen and swimming and all these things. You have so much more knowledge than them. And they're just these little nothings that know nothing.
Grey: When I'm around little kids, probably the thought that is in my head the most often is "you're just so useless at everything". Like you can't do... you can't do anything. You don't know anything about anything and you can't do anything. And you're just this huge burden on society that we tolerate because eventually you'll grow up and you will be useful. But not today.
Brady: But doesn't that make you feel good because you are useful? You're like "one day you be mighty like me. One day you will be able to buy food. One day you will be able to drive a car. One day you will be able to open a door, but now you can't. I am the god that can do these things". And you and the other adults look at each other knowingly like "we know, we know the stuff. We know how to open a door. They don't".
Grey: I guess I don't derive feelings of superiority by surrounding myself with uselesness.
Hello Internet #29, around the 1:00:00 mark.
When a very young child is learning their first language, they accumulate vocabulary mostly according to the whims of the world around them: what their family talks about, what's on TV. An older child can pick out books but will have difficulty really searching for something. The older you get, the more accurately you can search the internet, pick materials for your skill level, ask (well-formed, please!) questions on forums, etc.
Earlier I gave the children a point because they get constant immersion for free all the time, but that's passive immersion. Adults can do deliberate study and review and use tools like Anki to make sure that, even when we forget something, we'll get reminded of it in due time.
Learning a new language requires learning new grammar, obviously, but there are plenty of concepts and patterns that will be the same. When you learn the grammar for expressing "if A then B", you don't have to relearn the entire concept of 'if' as a baby does, you just have to learn the new words for saying it. The same goes for prefixes like anti-/un- or suffixes like -ic/-al and so forth.
If you're keeping score, you may feel like overall the kids come out on top. Even if an actively studying adult can outpace a child's language learning, the amount of effort and difficulty in reaching fluency makes it feel like more of a slog. However, I think this is better than simply throwing our hands in the air and saying that children just have special plasticy brains and they have the biological advantage and there's nothing we can do about it. Now that I've given my reasons for not believing in that as a primary cause, we can find some actionable takeaways by applying babies' strategies to our own learning.
They don't really have a choice → An adult learner should also strive to remove their choices. Stop fleeing back to the English safe zone. Change the language of your phone or computer. This is why Matt vs. Japan calls it the mass immersion approach.
This isn't always conducive to the best work/life/responsibilities balance, but babies don't really have those things so it's not a fair fight. Just try to get as close as you can.
Endless free time and constant immersion → I know I can't say to just create more free time, but look for ways to increase the time you spend listening. Any time you are not speaking to someone, or doing audio-based work, or forbidden from wearing earbuds, you could be listening.
Remove the friction between you and the process of listening. On my phone I use Musicolet which lets me have one queue for music and one queue for Korean so I can go from not-listening to listening very quickly.
At the moment, my current source of friction is wearing earbuds. They tend to get caught on stuff if outside my shirt, I don't like wearing them inside my shirt, and it is too easy to take them out and not put them back in. I could increase my listening hours by playing Korean on speaker at all times, but I don't for fear of bothering people.
Enthusiastic support from day one → It's difficult to give any advice here that isn't already commonplace. Find a friend online so you can encourage each other. If they're learning the same language as you, be careful that you don't wind up reinforcing mistakes (because you can't correct each other) or invent phrases that native speakers wouldn't actually use.
Not afraid to make mistakes → Imagine how would feel if you saw or heard someone make a mistake in English. Would you think they're dumb? No, of course not. So when you make a mistake in your target language, remember that although you might feel embarrassed, the listener probably doesn't mind. And if they do, you should find someone else to talk to.
I won't give too much advice here because I'm still bad at this part. I think I should write more or talk to myself more to practice without the pressure of having a listener. It's dangerous to invent new phrases on your own, but you can safely practice the phrases you already know, get better at saying them out loud, and improve pronunciation.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Thought: I should write a post with my thoughts about __blank__.
Counter-thought: The internet is already overflowing with people doing this, my take isn't unique, I don't have any novel information.
Counter-counter-thought: Who cares, it's my blog, text is cheap, maybe someone will find it interesting.
Counter-counter-counter-thought: I am contributing to the slow death of the internet as it is crushed under the weight of 7 billion people who think their thoughts need to be published for some reason.
Here's a hackernews post called What is your blog?. shadowsun7 says "My hard rule with the blog is that I should (as much as possible) write only about things I can verify through practice. None of that 'it sounds insightful because it is novel, but actually I came up with it in the shower and I've not actually tested it in real life'" to which _curious_ responded "If only more bloggers held the same standard, the internet would be a better place".
Meanwhile, swyx shared his "Learn in public" article, encouraging more publishing and "let the internet correct you when you are inevitably wrong". Does the doing-over-lurking mentality produce better individual results, but at the cost of polluting the internet for everybody else with permanent obelisks of bad early efforts? He even uses the phrase "learning exhaust".
Thought: I should share my thoughts about __blank__.
Counter-thought: "It is better to remain silent and be thought a fool than to speak and remove all doubt"
Counter-counter-thought: Oh please not again.
Counter-counter-counter-thought: "Wise men speak because they have something to say; fools because they have to say something"
Counter-counter-counter-counter-thought: git push
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>if __name__ == '__main__'
When you read other people's Python source code, you may find something like this at the very bottom of the file:
if __name__ == '__main__':
...
This is a construct that is confusing the first time you encounter it. if __name__ == '__main__'
is used to make a Python file that is importable by other Python files, as well as executable on its own.
In order to understand how it works and how to use it, there are a few background pieces of information you need to know.
When you are writing a program A.py
that imports another module B.py
, the code inside B.py
is executed just like if you ran B.py
by itself.
I know that sounds simple, but it's something people don't usually think about when practicing imports for the first time. Here, watch:
# B.py
print("I'm the B file!")
>python B.py
I'm the B file!
# A.py
print("I'm the A file, and I'm going to import B!")
import B
print("I'm all done importing B!")
>python A.py
I'm the A file, and I'm going to import B!
I'm the B file!
I'm all done importing B!
Suppose you write a file called hextools.py
so that you can practice converting between hex and ints.
# hextools.py
'''
This library provides functions for converting to and from hex.
'''
def int_to_hex(x):
'''
Python automatically starts it with 0x which we'll strip.
'''
return hex(x)[2:]
def hex_to_int(h):
return int(h, 16)
print(int_to_hex(4000))
>python hextools.py
fa0
It works great.
Then one day, you need to write a second program that also does some hex-int conversion. Well, instead of copying and pasting those functions, it makes sense to just import hextools.
# myprogram.py
import hextools
x = int(input('Please type a number: '))
print(x, 'in hex is', hextools.int_to_hex(x))
Now let's run that program.
>python myprogram.py
fa0
Please type a number:
That's annoying — the print statement inside hextools
is executed, and shows fa0 before myprogram
even asks for input. Well, that's because all the code inside hextools is executed simply by importing it. When I say "all the code", I'm referring to anything that's written on the global scope — anything which touches the left edge of the page. That means the def
statements which create the functions and, in this case, the print statement that we left there.
Now you know that importing a file causes that code to run. Hold that thought, it's time for the second piece of background information.
Python modules have some special variables in the global scope that are created automatically.
Try starting a python interpreter and calling dir
.
>python
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__']
>>> __name__
'__main__'
Ok so there's an automatic variable called __name__
which is a string that says '__main__'
but let's keep going to figure out what it means.
Let's start an interpreter with the -i
flag which runs everything in the file and then gives you the repl afterward.
>python -i hextools.py
fa0
>>> dir()
['__annotations__', '__builtins__', '__cached__', '__doc__', '__loader__',
'__name__', '__package__', '__spec__', 'hex_to_int', 'int_to_hex']
>>> __doc__
'\nThis library provides functions for converting to and from hex.\n'
>>> __name__
'__main__'
Well, there's that fa0 again. As you can see, there is a magical variable called __doc__
which automatically took the docstring that I wrote at the top of the file. I'm showing that to prove that this is exactly what the variables look like while Python is executing this file. And we see the variable __name__
which again says '__main__'
.
One more demonstration. Let's check that name variable again, but with an imported module:
>python
>>> import hextools
fa0
>>> __name__
'__main__'
>>> hextools.__doc__
'\nThis library provides functions for converting to and from hex.\n'
>>> hextools.__name__
'hextools'
Aha. So the __name__
of my Python repl is '__main__'
, but the __name__
of an imported module is its name.
>>> import os
>>> os.__name__
'os'
>>> import sys
>>> sys.__name__
'sys'
>>> import requests
>>> requests.__name__
'requests'
>>>
>>> __name__
'__main__'
There is only one module that can be '__main__'
, and that's whatever file we run directly. Anything you import will just have its own name.
Let's combine these two lessons together. Any code that you write on the global scope will be executed when you import that file into another. But, the magic variable __name__
will only say '__main__'
when you are running that file directly, otherwise it will just say the name of the module.
# B.py
print("I'm the B file, and my name is", __name__)
# A.py
print("I'm the A file, and I'm going to import B!")
import B
print("I'm all done importing B!")
>python B.py
I'm the B file, and my name is __main__
>python A.py
I'm the A file, and I'm going to import B!
I'm the B file, and my name is B
I'm all done importing B!
This should drive the point home:
# B.py
print("I'm the B file, and my name is", __name__)
if __name__ == '__main__':
print("The B file is being run directly!")
>python B.py
I'm the B file, and my name is __main__
The B file is being run directly!
>python A.py
I'm the A file, and I'm going to import B!
I'm the B file, and my name is B
I'm all done importing B!
Therefore, by putting code inside an if __name__ == '__main__'
, it will only run when you are running that file directly, and it will be skipped if the module is being imported by something else. There's nothing surprising about how this works. It's just an if statement!
Let's apply that change:
# hextools.py
'''
This library provides functions for converting to and from hex.
'''
import sys
def int_to_hex(x):
'''
Python automatically starts it with 0x which we'll strip.
'''
return hex(x)[2:]
def hex_to_int(h):
return int(h, 16)
if __name__ == '__main__':
x = int(sys.argv[1])
print(int_to_hex(x))
# myprogram.py
import hextools
x = int(input('Please type a number: '))
print(x, 'in hex is', hextools.int_to_hex(x))
>myprogram.py
Please type a number: 42
42 in hex is 2a
>hextools.py 42
2a
Now, hextools.py
can be run on its own with an argument on the commandline, and myprogram.py
can import hextools and use its functions without interruption.
Great job!
In some languages, like C or Java, all you have to do is define a function called main
and it will be run when you execute the file. Why does Python use this somewhat awkward magic string variable instead?
In my opinion it's for a few reasons. Firstly, Python spans a broad range of "program formality" levels. If you just write all your code on the global scope:
# someprogram.py
import os
for filename in os.listdir():
if os.path.isfile(filename) and filename.endswith('.temp'):
os.remove(filename)
Then you're basically treating Python like bash/batch (except a million times better). In order to allow for this kind of programming, Python is already predisposed to treat files as a list of instructions to execute in order. Compare that with Java where files are more like baskets full of methods and the order doesn't matter because main
is where things actually start running.
Consider also that in Python you can do this:
def f():
print('hello')
f()
def f():
print('world')
f()
hello
world
Which you can't do in a language like C or Java.
int f()
{
return 1;
}
int f()
{
return 2;
}
main.c:7:5: error: redefinition of 'f'
int f()
^
main.c:3:5: note: previous definition is here
int f()
^
class Main {
public static int f()
{
return 1;
}
public static int f()
{
return 2;
}
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Main.java:6: error: method f() is already defined in class Main
public static int f()
And then there's Javascript, which I guess must do a parsing pass before running but doesn't complain about redefines.
function f()
{
console.log("hello");
}
f();
function f()
{
console.log("world");
}
f();
world
world
But anyway. On the opposite end of the formality spectrum, you can write Python files where everything is tucked away into classes and functions and the file is designed as an import with no regard for command-line usage of that particular file. Well, if Python already has the predisposition to just run all the code on the global scope, why should there be a separate parsing mode, and how would it know which one to use?
That's not to say I love if __name__ == '__main__'
. I would prefer to have a separate __main__
magic variable that is True or False, then you can just if __main__:
. The __name__
string is still fine for other purposes, like printing the module to the screen.
As a matter of fact, whenever I upgrade a Python script from quick prototype to reusable code, I always move the main code into a C-like function called main
via this template:
def main(argv):
# At this point I usually do my argparse
return 0
if __name__ == '__main__':
raise SystemExit(main(sys.argv[1:]))
That's because if you make any variables inside if __name__ == '__main__'
, they will be part of the global scope which may have accidental side effects. For example:
# bad.py
import sys
def int_to_hex():
return hex(x)[2:]
if __name__ == '__main__':
x = int(sys.argv[1])
print(int_to_hex())
# Great, everything's ready to ship!
Spot the error.
Whereas by creating a main function, any variables in main
are local variables and are not accessible outside of it.
I understand that the examples shown here are very simplistic. Here are some links to my other programs which use ifmain in a purposeful way.
In a very large project with many files, it's more likely that you'll have a main launcher file, and none of the internals are very useful to run on their own. ifmain essentially bridges the gap to make single Python files useful as imports and standalone utilities.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>continue
is a keyword used to control for
and while
loops. It skips the rest of the current iteration, and starts the next one. This is different from break
which ends the entire loop.
This loop skips the number 3:
>>> for x in range(6):
... if x == 3:
... continue
... print(x)
...
0
1
2
4
5
Here, a bit more verbose:
>>> for x in range(6):
... print(f'{x} is above the continue')
... if x == 3:
... print(f'{x} is getting skipped')
... continue
... print(f'{x} is below the continue')
...
0 is above the continue
0 is below the continue
1 is above the continue
1 is below the continue
2 is above the continue
2 is below the continue
3 is above the continue
3 is getting skipped
4 is above the continue
4 is below the continue
5 is above the continue
5 is below the continue
This loop skips any directories that can't be listdir
'ed:
for directory in directories:
try:
filenames = os.listdir(directory)
except PermissionError:
continue
for filename in filenames:
...
If you're trying to perform an action on items that meet multiple criteria, you will either have to nest the conditions:
for submission in submissions:
if submission.author is not None:
if not submission.over_18:
if 'suggestion' in submission.title.lower():
print('Found:', submission.id)
or group all of the conditions into a single statement or boolean variable:
for submission in submissions:
if (
submission.author is not None
and not submission.over_18
and 'suggestion' in submission.title.lower()
):
print('Found:', submission.id)
But, with continue, we can achieve the same result in a more simple way:
for submission in submissions:
if submission.author is None:
continue
if submission.over_18:
continue
if 'suggestion' not in submission.title.lower():
continue
print('Found:', submission.id)
Notice that all of the conditions are the opposite of the originals. The mentality changes from "keep only the items with the right properties" to "discard the items with the wrong properties". This usage of continue is often called a "guard clause".
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>Generators are a type of iterable that create their contents on the fly. Unlike a list, whose entire contents are available before beginning any loops or manipulations, generators don't know how many items they will produce or when they will stop. They can even go on forever!
Writing a generator looks like writing a function, but instead of return
, you use yield
. The object which is yielded is what you'll get when you do a loop over the generator. This one lets you count to a billion:
def billion():
x = 0
while x < 1000000000:
yield x
x += 1
I purposely used a while
loop instead of for x in range()
to show the extra work.
Note that, unlike a return
statement, you can include more code after a yield
statement. Also notice that generators keep track of their internal state — the billion
generator has an x
that it increments every time you loop over it. You can imagine the code pausing after the yield
line, and resuming when you come back for the next cycle. Try this with some extra print statements to help visualize.
Generators can also take arguments. Here's a generator that counts to a custom amount:
def count_to(y):
x = 0
while x < y:
yield x
x += 1
Although generators look like functions when you're writing them, they feel more like classes when using them. Remember that generators don't calculate their contents until they are actually used in a loop, so simply doing:
numbers = count_to(100)
does not create a list of 100 numbers. It creates a new instance of the generator that is ready to be iterated over, like this:
numbers = count_to(100)
for number in numbers:
print(number)
or this:
for number in count_to(100):
print(number)
This should remind you of:
for number in range(100):
print(number)
because the range
class behaves a lot like a generator (but not exactly).
Generators are excellent for cases where using a list is infeasible or unnecessary. In order to loop over a list, you have to generate the entire thing first. If you're only going to use each item once, storing the entire list can be a big memory waste when a generator could take its place. With a generator, the items are created, used, and thrown away, so memory can be recycled.
Since generators can go on forever, they're great for abstracting out ugly while
loops, so you can get down to business faster.
To get a single item from a generator without looping, use next(generator)
.
Generators pause and resume a lot, but they still flow like normal functions. As long as there is no endless while
loop inside, they'll come to an end at some point. When a generator is all finished, it will raise a StopIteration
exception every time you try to do next()
on it. Luckily, for
loops will detect this automatically and stop themselves.
>>> g = count_to(10)
>>> l = list(g)
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Earlier, I said that generators use yield
instead of return
, but in fact you can include a return statement too. If it is encountered, it will raise a StopIteration
, and the generator will not resume even if there is more code.
>>> def generator():
... yield 1
... return 2
... yield 3
...
>>>
>>> g = generator()
>>> next(g)
1
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration: 2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
Notice that the 2 became part of the StopIteration that was raised at that line.
Suppose you're getting data from an imaginary website which sends you items in groups of 100. You want to let the user loop over the items without having to worry about the groups.
def item_generator(url):
page = 0
while True:
# get_items is a pretend method that collects the 100 items from that page
batch = get_items(url, page=page)
if len(batch) == 0:
# for this imaginary website, the batch will be empty when that page
# doesn't have any items on it.
break
for item in batch:
# by yielding individual items, the user can just do a for loop
# over this generator and get them all one by one.
yield item
page += 1
# When the while loop breaks, we reach the end of the function body,
# concluding the generator.
Now the user can just do this:
comments = item_generator('http://example.com/user/voussoir/comments')
for comment in comments:
print(comment.body)
Stack Overflow - What are the main uses for yield from
? — If you like recursive functions, how about recursive generators?
Stack Overflow - Python generator send
function purpose? — This quickly dives out of "quick tips" territory.
If you would like to subscribe for more, add this to your RSS reader: https://voussoir.net/writing/writing.atom
]]>