I'm working on submitting my climbing record to Guinness. They require video--including slow motion video!--but they have a 1gb limit on uploads, and recommend splitting videos into 1gb portions with five second overlap. I made a little python script to do this using ffmpeg. You can specify the maximum size (default: 999999999 bytes) and the aimed-at overlap (default: 6 seconds, to be on the safe side for Guinness), and it will estimate how many parts you need, and split the file into approximately these many. If any of the resulting parts is too big, it will try again with more parts.
Wednesday, July 19, 2023
Monday, December 13, 2021
An introduction to simple motion detection with Python and OpenCV
Sunday, May 24, 2020
Wii Remote Lightgun
Friday, December 20, 2019
Python script for Nanson and Black voting
I made a handy little python script for tabulating group votes with more than two candidates using either Black’s Procedure or Nanson’s Method. Both algorithms are Condorcet compliant. The algorithms require as input a text file with the ballots and control information. Once the algorithm finds a winner (or a bunch of tied winners), it deletes them from the ballots and repeats.
For instance suppose sample.txt contains:
method Black's
require 3
ballot Mickey Donald Sonic
ballot Mickey Sonic Donald
ballot Sonic Mickey Donald
Then:
$ python3 vote.py sample.txt
Options: {'method': "Black's", 'require': 3}
Ballots: 3
Valid ballots: 3
Candidates: ['Donald', 'Mickey', 'Sonic']
Method: Black's
position 1 (Condorcet): Mickey
position 2 (Condorcet): Sonic
position 3: Donald
Black’s Procedure works as follows at each stage: see if there is a Condorcet winner; if not, look for a Borda winner (the first person on each ballot gets a (reversed) Borda score of 0 points; the second gets 1 point; and so on; persons not on a ballot get n points where there are n on the ballot; the winner is determined by the lowest sum of points; note that by default the ballots are modified at subsequent stages by deleting candidates who were already selected, which means the Borda scores change from stage to stage). Nanson’s Method deletes everyone with poorer-than-average Borda score, re-ranks, and repeats until there is a winner or a tie. This is also guaranteed to return a Condorcet winner if there is one.
The code marks winners that were Condorcet winners. That may be helpful to group deliberation as it shows that the decision is bit more robust in that case. (Though a Condorcet winner in kth place, with some non-Condorcet winners before, may not mean much if the earlier winners are dubious.)
The require line specifies how many entries a ballot must contain to be valid (by default, all ballots are valid, even ones with varying numbers of votes; any unranked candidates count as tied after the last ranked candidate). The ballot lines contain the candidates that someone voted for, in order from best to least good. Candidate names are case sensitive and cannot contain spaces. To save typing, one can also introduce abbreviations with the key entry. For instance:
method Black's
require 3
key m Mickey
key d Donald
key s Sonic
ballot m d s
ballot m s d
ballot s m d
Wednesday, October 11, 2017
MIDI fruit piano
While tweaking the project, I learned that MIDI format is really simple, so now the fruit-piano sends notes to the computer via MIDI-over-serial-over-USB, and so one can presumably use the fruit-piano as a keyboard for various kinds of desktop music software.
Instructions are here. Code is here.
If you look at the picture carefully, you'll see that I cheated. We didn't have the eight oranges for the C major scale that my eldest daughter thought we should have, so two of the keys are soda cans.
Wednesday, September 20, 2017
The Probabilistic Counterexampler
Every so often someone asks me if some piece of probabilistic reasoning works. For instance, today I got a query from a grad student whether
- P(A|C)>P(A|B) implies P(A|B ∨ C)>P(A|B).
Of course, I could think about it each time somebody asks me something. But why think when a computer can solve a problem by brute force?
So, last spring I wrote a quick and dirty python program that looks for counterexamples to questions like that simply by considering situations with three dice, and iterating over all the possible combinations of subsets A, B and C of the state space (with some reduction due to symmetries).
The program is still quick and dirty, but at least I made the premises and conclusions not be hardcoded. You can get it here.
For instance, for the query above, you can run:
python probab-reasoning.py "P(a,c)>P(a,b)" "P(a,b|c)>P(a,b)"
(The vertical bars are disjunction, not conditional probability. Conditional probability uses commas.) The result is:
a={1}, b={1, 2}, c={1}
a={1}, b={1, 2, 3}, c={1}
a={1}, b={1, 2, 3}, c={1, 2}
a={1}, b={1, 2, 3}, c={1, 3}
a={1}, b={1, 2, 3}, c={1, 4}
...
So, lots of counterexamples. On the other hand, you can do this:
python probab-reasoning.py "P(a)*P(b)==P(a&b)" "P(b)>0" "P(a,b)==P(a)"
and it will tell you no counterexamples were found. Of course, that doesn’t prove that the result is true, but in this case it is.
The general operation is that you install python (either 2.7 or 3.x) and use a commandline to run:
python probab-reason.py premise1 premise2 ... conclusions
You can use any single letter variables for events, other than P
, and the operations &
(conjunction), |
(disjunction) and ~
(negation) between the events. You can use conditional probability P(a,b)
and unconditional probability P(a)
. You can use standard arithmetical and comparison operators on probabilities. Make sure that you use python’s operators. For instance, equality is ==
, not =
. You should also use python’s boolean operations when you are not working with events: e.g., “P(a)==1 and P(b)==0.5”.
Any premise or conclusion that requires conditionalization on a probability zero event to evaluate automatically counts as false.
You can use up to five single-letter variables and you can also specify the number of sides the die has prior to listing the premises. E.g.:
python probab-reasoning.py 8 "P(a)*P(b)==P(a&b)" "P(b)>0" "P(a,b)==P(a)"
Sunday, March 5, 2017
Super-simple fractal terrain generator
The algorithm is no doubt known, but some quick searches for terrain generation algorithms didn't turn it up, so I am posting for people's convenience.
There are some artifacts at internal triangle boundaries that better algorithms presumably don't have, but the algorithm is super simple to implement, and because it is based on triangles it directly makes a triangular mesh. Here is some code which does this, starting with a hexagon divided into six equilateral triangles, and putting out an STL file.
Wednesday, February 22, 2017
Going from 2D drawings to 3D printing
After Valentine's, I still worked on refining the Python code that did the inflation. The code is now an easy to use Inkscape extension, which adds the ability to save to an inflated SCAD or STL file. The official repository is here.
The final algorithm I settled on is a non-linear scheme that sets the height of the inflation of a 2D image at a given point in the image x by approximating the Lp norm (E(Txp))1/p of the exit time Tx of a random walk started at x. For further adjustment, you can replace Tx with min(Tx,K) where K is exponentially distributed, which flattens the inflation in inner regions. The code could use a lot of optimization (using pypy instead of cpython improves runtimes by a factor of 10, but Inkscape only bundles python) as on my laptop the code takes about 45 seconds with default settings on one of my simple test images.
While my original Valentine's day card used p=1, I have since found that p=2 produces more nicely rounded output.
Thursday, August 25, 2016
Syntax and semantics
One of the things that I've been puzzled by for a long time is the distinction between syntax and semantics. Start with this syntactically flawed bit of English:
- Obama equals.
- Let xyzzing be sitting if the temperature is more than 34 degrees and let it be equalling otherwise. Obama xyzzes.
One might object that the second sentence of (2) is syntactically correct even when the temperature is 30 degrees. It's just that it then has a semantic value of undefined. This move is similar to how we might analyze this bit of Python code:
def a(f): print(f(1)) def g(x,y): x+y def h(x): 2*x a(h if temperatureSensor()>34 else g)This code will crash with
TypeError: <lambda>() takes exactly 2 arguments (1 given)when the temperature sensor value is, say, 30. But the behavior of a program, including crashing, is a matter of semantics. The Python standard (I assume) specifies that the program is going to crash in this way. I could catch the TypeError if I liked with
try/except
, and make the program politely print "Sorry!" when that happens instead of crashing. There is no syntactic problem: print(f(1))
is always a perfectly syntactically correct bit of code, even though it throws a TypeError whenever it's called with f
having only one argument.I think the move to say that it is the semantic value of the second sentence of (2) that depends on temperature, not its grammaticality, is plausible. But this move allows for a different way of attacking the distinction between syntax and semantics. Once we've admitted that the second sentence of (2) is always grammatical but sometimes has the undefined value, we can say that (1) is grammatically correct, but always has the semantic value of undefined, and the same is true for anything else that we didn't want to consider grammatically correct.
One might then try to recapture something like the syntax/semantics distinction by saying things like this: an item is syntactically incorrect in a given context provided that it's a priori that its semantic value in that context is undefined. This would mean that (2) is syntactically correct, but the following is not:
- Let xyzzing be sitting if Fermat's Last Theorem is false and let it be equalling otherwise. Obama xyzzes.
It may, however, be the case that even if there is no general distinction between syntax and semantics, in the case of particular languages or families of languages one can draw a line in the sand for convenience of linguistic analysis. But as a rule of thumb, nothing philosophically or semantically deep should rely on that line.
Now it's time to be a bit of a hypocrite and prepare my intermediate logic lecture, where instilling the classical distinction between syntax and semantics is one of my course objectives. But FOL is a special case where the distinction makes good sense.
Wednesday, August 10, 2016
Random dithering of images
One could come up with a 3D version of one of these algorithms, but I went for a different tack: random dithering. Random dithering isn't much used these days, because it is thought to produce really bad results. But while that would no doubt be true with a two-color palette, it doesn't seem to be true with a larger palette, like my Minecraft 82 block palette. The method I used was to add to each color channel a random perturbation, with distribution either uniform or a cut-off Gaussian, and the results were gratifying. Not quite as good as Floyd-Steinberg, but close.
The original is on the right. "Gaussian X/Y" means a perturbation with sigma X, cut off at -Y and Y. "Uniform X" means a perturbation uniform over the interval [-X,X].
And here's how it looks wrapped on an egg (uniform 20, I think):
Actually, on this cartoon stuff, the dithering is hardly needed. A photograph benefits more from the dithering. It's a dung beetle I photographed outside of our house some years ago.
Original:
Minecraft renderings:
In both cases, uniform 20 and Gaussian 20/30 seem good enough. Source code here.
Tuesday, July 19, 2016
Falling-block game in Minecraft
Wednesday, June 29, 2016
IRToWebThingy
For quite some time, my older daughter has wanted me to make her Great Wolf Lodge Magiquest wand do something at home. So I made a simple IRToWebThingy (the link gives build instructions). It takes infrared signals in many different infrared remote controls and makes them available over WiFi. As a result, we can now watch Netflix with a laptop and a projector and the ceiling and play/pause with the Magiquest wand (and adjust volume with our DVD remote) with a pretty simple python script. My son (with some help) made a 3D etch-a-sketch script that lets him draw in Minecraft with the DVD remote. I made a fun script that lets you fly a pig in Minecraft with a Syma S107 helicopter remote (see photo). You can even control rooted Android devices with IR remotes and shell scripts.
Sunday, June 26, 2016
Teaching programming with Python and Minecraft
Last summer, I taught programming to gifted kids with Python and Minecraft. Here's my Instructable giving a curriculum for a course like that.
Thursday, June 23, 2016
RaspberryJamMod for Minecraft/Forge 1.10
My RaspberryJamMod, which enables the Minecraft PI API for Python programming, has been updated to work with Minecraft/Forge 1.10. Still alpha-quality, but everything I've tried seems to work.
Sunday, March 27, 2016
Christ is risen!
Happy Easter, everyone!
Here are Easter eggs in Minecraft generated using my pysanka.py python script (included with Raspberry Jam Mod). The middle one is based on the design here (I am trusting that the amount of deformation and transformation is sufficient that it not be a copyright issue to post the Minecraft version).Here are instructions on making eggs like that.
Tuesday, December 29, 2015
RaspberryJamMod for Forge/Minecraft 1.8.8
I just updated RaspberryJamMod, which allows one to run python code in Minecraft (using a variant of the Raspberry PI Minecraft API), to work with Minecraft 1.8.8 (with the latest beta of Forge). Merry Christmas!
Here's a rebel fighter from Space Janitors (using a mesh in their Janitor's Closet) generated with the render.py script.