Thursday, February 21, 2013

HOWTO Find the Number of Pixels in a MM with Javascript

This is a simple trick to find the number of pixels in a millimeter using jQuery.

Code

function pixelsPerMM()
{
$("body").append("<div id='onebyone' style='width:1mm;height:1mm;display:hidden;'></div>");
var pixels = $("#onebyone").width();
$("#onebyone").remove();
return pixels;
}

How It Works

  1. Adds a new element that is 1mm x 1mm to the page.
  2. Requests the width (in pixels) of that element.
  3. Deletes the element.
It is probably a good idea not to call this repeatedly in your code, as changing the web document in this manner is slow.

Why Use It

If you have an interface that you want to be exactly the same on every device, but you can't lay out the entire thing using CSS i.e. some elements are dynamically generated using Javascript, this would be a good method.

Saturday, February 16, 2013

When You Are Justified in Complaining About FOSS

LibreOffice 4.0 has recently been released, and has received a lot of unfounded criticism over its new ability to be themed using Firefox Personas. Now would be a good time to go over when it is acceptable or not to complain about FOSS, as there seems to be quite a lot of confusion about that.

Most of the time, you should not complain about FOSS like this because:
  • You got it for free.
  • If you don't like it, you don't have to use it.
  • You are encouraged to fix the things that annoy you.
  • You did not do any work.
However, there are a few cases where you are allowed to complain about FOSS:
  • When the product destroys your data.
  • When there is no way to contribute to the project other than forking it. (e.g. Android)
  • When you have contributed code/patches that are widely desired, but the maintainers will not accept them.
  • When you are paying the developers to make changes, and they are not.

Back to Personas!

All of the complaints the LO team have received over this issue are unfounded because the software is free, does not force you to update to the newest version, has a remarkably open ecosystem (1500 merges from 3.0 to 4.0), and the product still works without ever using that feature.

Not only does LO 4.0 work better than the 3.X branches, it is vastly superior in speed, supported formats, and code maintainability.

This whole issue will seem silly in two months when Ubuntu releases a branded LO using a theme that adds subtleties to the document editor that perfectly integrate it with the platform, but until then hopefully these guidelines will suffice for indignant posters.

Tuesday, February 12, 2013

HOWTO Make a Quick and Dirty (Pseudo)Random Number Generator

If you ever need to build your own quick and dirty (pseudo-)random number generator it actually isn't that hard. This generator is used in various real-world systems:
  • Visual Basic (to version 6)
  • A few ANSI C implementations, including glibc
  • Java's Random library
The implementation will iterate over all numbers [0,m) when using proper a, m ,c's. 1

Implementation

#include <stdio.h>
#include <unistd.h>

const long m = 4294967296; // 2 ^ 32
const long a = 1103515245;
const long c = 12345;

long lastX = 0;

long nrandom() {
lastX = (a * lastX + c) % m;
return lastX;
}

void seed(int num)
{
lastX = num;
}

int main()
{
int i;

seed(getpid());

for(i = 0; i < 1000; i++)
printf("%li\n", nrandom());
}
Note that this implementation only generates m pseudorandom numbers, in this case 4,294,967,296; so if you need more, you'll want to use a different algorithm.

  1. These conditions require some discrete mathematics that are too long to go in to here; it involves coprime numbers and recurrence relations. (Please point out if I've missed some simple explaination in the comments, I'm fairly new to this!)

Wednesday, February 6, 2013

HOWTO Fix Flash in Chrome + Ubuntu 12.10

After a recent Chrome update, I was left without flash for this browser, which by the way handles Pandora way better than Firefox does on the same platform.
A quick fix is all that is needed:
  1. Type chrome://plugins/ in to your URL bar.
  2. At the upper right, press "Details"
  3. Scroll down to the Adobe Flash Player entry, there should be two sub-entries, these are versions of Flash Chrome can use.
  4. Disable the entry that looks like this (should be the first one):
    Name:   Shockwave Flash
    Location: /home/user/.config/google-chrome/PepperFlash/11.5.31.138/libpepflashplayer.so
    Type: PPAPI (out-of-process)

    MIME types:
    MIME type Description File extensions
    application/x-shockwave-flash Shockwave Flash .swf
    application/futuresplash Shockwave Flash .spl

  5. Restart the browser.
For some reason the flashplayer using the pepper API appears not to be working, so you'll just have to stick with the one that was installed to your platform through the package manager (a safer bet anyway).

Monday, February 4, 2013

HOWTO Use Python "for in" and "for else" Loops

This is a short guide to the subtleties of Python for loops, especially for those programmers from Java/C++ that may miss some of the best features because those languages don't have any equivalent, it covers:
  • The basic for loop
  • Looping over dictionaries
  • Using the for else loop

The Basic for loop

If you come from a Java/C++/PHP background, you're used to two different for loops foreach and for. Python only has one of these, the more powerful foreach.
In Java, your for loop would look something like this:
for(int i = 0; i < 10; i += 2)
{
System.out.println(i);
}
In Python, the same loop would look like;
for i in range(0, 10, 2):
print(i)
The range function returns a list of numbers 0 to 10 incremented by 2.
If you wanted 0-9 inclusive, the loop would be even more simple.
for foo in range(10):
print(foo)
In this same manner, you can replace the range() with any list:
for j in [1,1,2,3,5]:
print(j)

Looping over Dictionaries (maps)

Maps are a very handy Python builtin feature, allowing you to create arbitrary key->value pairs.
{
"key":"value",
"bob":"smith",
"age":13,
"dob":(2012,01,01)
}
You can quickly loop over key->value pairs in a dictionary by using the following:
for key, value in a.items():
print("{} -> {}".format(key, value))
Note that this is much faster than looping over the keys, then looking up the value for each key inside the for loop. The items function returns a list of tuples where the first value is the key, and the second a value.

In fact, you can loop over any list of tuples in a similar manner:
b = [("Perro", 1, ["Canis", "lupis"]),
("Gato", 2, ["Felis", "catus"])]

for name, id, scientific in b:
print("Name: {} ID: {} Breed: {}".format(name, id, " ".join(scientific)))

The Magic of the for else Loop

If you've ever wanted to check if something happened within a for loop you can use an else block after your for loop:
for i in ["foo","bar"]:
if i == "baz":
break
else:
# happens if break is not called, meaning "baz" was not found
return -1

# i is set to the location of "baz"
return i
The example above tries to find the location of a specified string in a list of strings, if found it returns the index, otherwise -1. Of course there are far easier ways to do this, but you get the idea.