The recent post on Hacker News about #! semantics surprised me. I had always assumed that a shebang line like
#! /usr/bin/prog -a -b
Would be equivalent to calling
$ /usr/bin/prog -a -b <file>
The recent post on Hacker News about #! semantics surprised me. I had always assumed that a shebang line like
#! /usr/bin/prog -a -b
Would be equivalent to calling
$ /usr/bin/prog -a -b <file>
The point of this post is an attempt to calculate e to given precision in bash, a challenge given in a job listing that I saw recently. I kind of got nerd sniped. I wrote this as I went along, so there may be inconsistencies.
###First attempt###
The obvious method to compute e is as the infinite sum of 1/n!, n from 0 to ∞. This converges quickly, but how far do we have to calculate to get the n'th digit of e? We can deal with that later.
We obviously need a factorial function.
fac() {
My root filesystem is on an SD card, and when I got a Raspberry Pi I decided to swap that SD card for a larger one and use the original in the Pi. This post chronicles my attempts to copy the filesystem.
I only have one SD card slot, which means I need to copy through an intermediate storage device. I have a backup disk, so that's not a problem. I also need another operating system, since I can't use my normal one while copying things to the new SD card. (I also no longer have the original OS on my netbook, because I've been using that partition for swap space.) Years ago I put a copy of Ubuntu on a USB stick "in case of emergencies" (I think this is the first time I've needed it), so that's not a problem either.
The new SD card already has one full-size partition, so the first step is to install ext3 on it:
mkfs.ext3 /dev/sdd1
After installing Arch on my Raspberry Pi, internet worked out of the box: I could plug it into the router, turn it on, ssh in and start downloading things. But the router is in my housemate's bedroom, which isn't ideal. If I want the Pi to be connected to the internet in my room, I need it to be connected to my laptop. (Another option would be a USB wifi dongle, of course.) This is how I did it. Much credit goes to the Ubuntu wiki's Connection sharing page.
I should disclaim that I don't fully understand networking stuff, and some of what I say might be wrong. I also didn't write this as I was going; so while I've consulted my browser and shell histories, it's possible I've forgotten some steps.
My laptop is running Gentoo, and this is where most of the work has to be done. It connects to the internet through wifi, on interface wlan0
. The ethernet port is eth0
, and eth0
is also the name of the ethernet port on the Pi.
Step zero: plug ev
This is a dead-simple way to test that GPIO on the Raspberry Pi is working. I have an SKPang Raspberry Pi starter kit A. But all you need is
Some notes on getting Arch to work on the RPi.
At first, running shutdown -r now
would cause the RPi to halt but not restart. A firmware upgrade fixed this. Install git
, then clone and run rpi-update
. (The script requires git
to run, so you can't just copy it from the repository.)
pacman
used to complain about being out of date, and ask if I wanted to upgrade; and it would complain about udev-oxnas
and systemd-tools
both wanting to own udev
. (I no longer remember exactly what the errors were.)
The MCP23017 is an I/O expander chip. It has 16 GPIO pins which you can control using an I2C interface using two pins from a Raspberry Pi, plus a power source and sink (which can also come from the Pi). It's not quite as simple as directly controlling the Pi's GPIO pins, but it's not complicated, either.
You need to install i2c-tools
, which is probably in your distribution's package manager. You also need a kernel with I2C support; you might need to modprobe i2c-dev
. It would presumably be possible to do without either of these things, and bitbang the I2C protocol over GPIO, but I don't understand the protocol well enough to try.
On pin numbering: if you like, you can refer to the datasheet for the MCP23017. There's a small dot in one corner of the chip, with a semi-circular cut-out at that end. The pin near
The Liang-Barsky algorithm is a cheap way to find the intersection points between a line segment and an axis-aligned rectangle. It's a simple algorithm, but the resources I was pointed to didn't have particularly good explanations, so I tried to write a better one.
Consider a rectangle defined by x_min ≤ x ≤ x_max and y_min ≤ y ≤ y_max, and a line segment from (x_0, y_0) to (x_0 + Δ_x, y_0 + Δ_y). We'll be assuming at least one of Δ_x and Δ_y is nonzero.
(I'm working with Flash, so I'll be using the convention that y increases as you go down.)
We want to distinguish between the following cases:
Adafruit sells an 8x8 LED matrix which you can control from a Raspberry Pi using I2C. Unfortunately they only provide Arduino code; I've only used I2C through the programs i2cset
, i2cget
, i2cdump
and i2cdetect
available from the i2c-tools
package; and it wasn't immediately obvious how to use Adafruit's code to control the matrix from the Pi.
Fortunately, it turns out to be quite simple. i2c-tools
seems to assume a register-based model of I2C devices, where the target device has up to 256 pointers which can be read and written. This doesn't seem to suit the HT16K33 chip (datasheet) that the matrix backpack uses. For example, when I ran i2cdump
, which gets the value of each register, it started to blink a picture at me. At least I knew it was working.
Setting individual LEDs works much as you might expect. Every row has a single register, the eight bits of that register correspond to the eight LEDs on
The Arduino wiki has a page on getting an Arduino to work with Gentoo. It didn't work for me, so I'm posting what did work here. I'm hesitant to put this on the wiki page directly, because it would require removing a lot of information that was put there for a reason. But, here's what seems to have worked for me. Caveats: I've only tested with an Uno and a Leonardo; and in the process of getting them to work, I did a lot of other things that I don't think made a difference, but I don't remember what half of them were, so who knows?
Device Drivers -> USB support -> USB Modem (CDC ACM) support
. If you're not sure whether you have it, run zgrep USB_ACM
. If you do, there'll be a line CONFIG_USB_ACM=y
or =m
. It's okay to have as a module, and building a module is faster than recompiling your entire kernel and doesn't require a reboot. I'm not going to go into the process here, though.avrdude
and `a