Tuesday, March 5, 2013

Hacking Respondus LockDown Browser 2.0

It has been about a year since I've visited this topic, and I've decided that it is indeed worth revisiting. But first, a few reasons that I'm doing this so nobody gets the wrong idea:
  • To prove Respondus LockDown Browser does not circumvent cheating
  • To encourage anyone left using this technology to change their assessment methodology to other means, such as projects because:
    • They are more effective
    • It is just as easy to determine if a student cheated
    • They test ability to apply instead of memorization (life is open book, what you need to know is how to apply what you know!)
  • To boost blog viewership (I write to be read, and Respondus is one of my most read posts)

The Technique

I have devised a better way of "hacking" Respondus that does not involve the use of monitoring system calls, although that would be equally viable and was what I had originally intended to do.
This version works better, is cleaner, and anyone can edit it when it stops working. Essentially, it just modifies Respondus' window and opens other programs with button presses.

How To Run

  1. Download the code, and save it to a file on your desktop called Respondus.ahk
  2. Download and install Auto Hot Key
  3. Close all other windows on your desktop.
  4. Right click the Respondus.ahk file and choose "Run As Administrator"
Code tested on Windows 8/XP. You might need to change the first line in 64 bit versions of Windows 7/Vista to reflect another path to LockDown.exe.

Code

Run, C:\Program Files\Respondus LockDown Browser\LockDown.exe

WinWait, Respondus LockDown Browser
WinSet, AlwaysOnTop, Off, Respondus LockDown Browser
WinSet, Enable, , Respondus LockDown Browser


Gui, Add, Button, default, &Show IE
Gui, Add, Button, default, &Hide Respondus
Gui, Add, Button, default, &Show Respondus
Gui, Add, Button, default, &Maximize All
Gui, Show,, Subversion Menu

WinSet, AlwaysOnTop, On, Subversion Menu
return

ButtonShowIE:
Run, IEXPLORE.EXE http://onehourhacks.blogspot.com
WinWait, One Hour Hacks - Windows Internet Explorer
WinMove, One Hour Hacks - Windows Internet Explorer, , (A_ScreenWidth/2), 0, (A_ScreenWidth/2), (A_ScreenHeight),,
return

ButtonHideRespondus:
WinHide, Respondus LockDown Browser
return

ButtonMaximizeAll:
WinGet, WindowList, List
Loop, %WindowList%
{
WinMaximize, % "ahk_id " . WindowList%A_Index%
}

WinHide, Respondus LockDown Browser
return

ButtonShowRespondus:
WinShow, Respondus LockDown Browser
return

ButtonLeftSideRespondus:
WinMove, Respondus LockDown Browser, , 0, 0, (A_ScreenWidth/2), (A_ScreenHeight),,
return

ButtonFullScreenRespondus:
WinMove, Respondus LockDown Browser, , 0, 0, (A_ScreenWidth), (A_ScreenHeight),,
return

GuiClose:
ExitApp

Friday, March 1, 2013

The Case Against Customizability

Three words on building customizability in to your product: don't do it. This is to the products that allow users to change colors, organize panels, choose icons, etc.

Users have a hard enough time with finding functionality

Watch your technophobic family members try to attach an image to an email. While you may have no problem getting through menus to do it, they often do. Remember: there are more of them than us.
Customizability just gets in the way for super-users because they have better ways of doing it.

Your Product is a Tool, Not a Piece of Art

Your goal as a designer should be to minimize the amount of time on your software because it should just work.
Get your users back to the real world where they can go create art or enjoy it.

Troubleshooting/Documenting is Hard With Customizability

When you write tutorials, it is easy when everything is the same. Customizability makes it harder to follow tutorials, especially if the writer has a custom setup.
Users will also find it harder to help one another, which means more support is needed from you!

It Leads to Messy Code

Just think about rearranging components on the web, you need a place to save the information, a new server interface for submitting it, security procedures over that to make sure it isn't an attack vector, another library user-side to test in every browser.

Most of the Users Will Never Do It

Take BlackBoard for example, I TA a bit, and of all the students I've seen pull up blackboard, not one of them has changed the style or layout as they're allowed to; nobody wants to spend the time on a product they use twice a day.

Your time is better spent on usability

iGoogle was a great example of this, instead of needing a homepage like they used to, users can now just type what they want in to the search box and get information relevant to them.
Spend your time figuring out why users would need to customize, and eliminating that need.

Final Note

I'm not advocating that you throw everything in to code, no no! I fully support MVC, that is how superusers can change your environment to suit them best. If you must allow user tweaks to your software, like moving around menus, put it in a plugin so when your code gets updated, the whole software doesn't break.

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.