Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Wednesday, July 19, 2023

Video splitter python script

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.

Monday, December 13, 2021

An introduction to simple motion detection with Python and OpenCV

One of my kids really liked a cool thing in a children's museum where they had a camera pointed down a hallway, with a screen, and if you waved your hands in certain areas you got to play music. So I decided to make something like this myself. I found this tutorial and with its help produced some simple code. I then wrote up an Instructable explaining how the code works.



Sunday, May 24, 2020

Wii Remote Lightgun

The Wii Remote sort of works like a lightgun, but not quite. It has a camera that can track four infrared LEDs, but the LEDs it uses are normally arranged in a straight line in the Wii sensor bar, which is mathematically insufficient for figuring out where exactly the Wii Remote is pointed. If, however, we put two infrared LEDs on top of a TV and two on the bottom, then one could use homography calculations to figure out where the Wii Remote is pointing, and use it as a lightgun. I wrote some code for my Raspberry PI that does this, and together with a 3D printable handle and sights the Wii Remote becomes a nice lightgun for retro games. Instructions are here.


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

My daughters and I saw a Makey-Makey banana piano at a local fair, and they thought it was cool. So I made an Arduino(clone) fruit piano, using capacitive sensing, and a Python program on a computer that plays polyphonic music. It's super-simple, as it uses the ADCTouch library which doesn't need any electronic components besides the Arduino(clone), and it's better than the banana piano as it doesn't require the user to be grounded.

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

  1. 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

Here's a very simple algorithm for generating random terrains: Start with a equilateral triangle in the x-y plane. Add a uniformly and symmetrically distributed random z-offset to each vertex. Bisect each resulting edge and add a random z-offset at the newly added point, half of the magnitude of the random offsets earlier. Repeat several times.

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

I wanted make a 3D-printable Valentine's day card for my wife, with an inflated red heart on a white background, so I spent perhaps too much time playing with algorithms to "inflate" a 2D drawing of a heart into a 3D polyhedron that I can load into OpenSCAD. Here's the card I ended up with.

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:

  1. Obama equals.
It is syntactically flawed, because "to equal" is a transitive verb, and a sentence that applies an intransitive verb to a single argument is ungrammatical, just as an atomic sentence in First Order Logic that applies a binary predicate to one argument is ungrammatical. (I leave open the further question whether "Obama equals Obama" is grammatically correct; maybe the arguments of the English "equals" have to be quantities.) This is a matter of syntax. But now consider this more complicated bit of language:
  1. Let xyzzing be sitting if the temperature is more than 34 degrees and let it be equalling otherwise. Obama xyzzes.
My second sentence makes perfect sense when the temperature is 40 degrees, but is ungrammatical in exactly the same way that (1) is when the temperature is 30 degrees. Its grammaticality is, thus, semantically dependent.

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:

  1. Let xyzzing be sitting if Fermat's Last Theorem is false and let it be equalling otherwise. Obama xyzzes.
For it's a priori that Fermat's Last Theorem is true. I think, though, that a syntax/semantics distinction that distinguishes (2) from (3) is too far from the classical distinction to count as an account of it.

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

I wanted to wrap a rectangular texture of, say, the earth around a sphere in Minecraft to make a 3D image (using RaspberryJamMod and Python). The problem was that my color palette would be limited to Minecraft blocks, and not all blocks would be appropriate--with my son's help, I selected a subset of 82 that would work well for general purpose image rendering. So I needed to reduce the color in the texture. One could just choose the nearest color available for each point in the image, but that would lose a lot of detail. The standard family of techniques to solve this is dithering. However, most dithering algorithms like Floyd-Steinberg or ordered dithering are designed for flat two-dimensional 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

Over a recent trip, I had fun writing a little Python implementation of the classic 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.


Friday, July 10, 2015

More Minecraft fractals

I posted an Instructable with a whole bunch of fractals in Minecraft via Python scripts.




Thursday, June 4, 2015

Python coding for Android Minecraft PE

I've been sensitized to the fact that there are many children who have no access to a PC but do have access to a smartphone. So in the interests of computer science education, I made a mod that allows for Python scripting of Minecraft Pocket Edition on Android. Instructions and links are here. The screenshots are from my Galaxy S3.






Tuesday, April 21, 2015

Deep Space Nine in Minecraft

My big kids and I are Deep Space 9 fans. Here's a Deep Space 9 station rendered in Minecraft using our modifications to Martin O'Hanlon's rendering script from a mesh by Joerg Gerlach. For more on python and Minecraft, see here.


Saturday, March 28, 2015

Instructable for python coding for Minecraft

If anybody is interested, I wrote up an Instructable for python coding for Minecraft using my Raspberry Jam Mod.