Zero Wind – Jamie Wong Inside the mind of a Waterloo Software Engineering student

27Dec/093

UWAngel-CLI

Screen shot 2009-12-27 at 1.39.50 AM

Near the end of the semester, I was getting kind of tired of navigating UW-ACE so frequently through my browsing and opening all the different tabs to grab all the files I wanted. While all the pretty graphics make for a decent user interface, it reduces the speed of the service.

But aside from that, I like being able to do as much as I possibly can from the console.

So I made a Command Line Interface (CLI) for UW-ACE in php using cUrl. I built in on my Macbook Pro in Snow Leopard, but it should work just fine on any *nix machine, and possibly in Cygwin or other emulators.

As always, source is available on github: UWAngel-CLI @ Github.

Since I always like to post snippets of code from my projects that may be universally useful, I'll do that here too.

CLI Colour in PHP
cli_colours.php included in the UWAngel-CLI source is just a collection of constants which allow you to print out colours in your CLI scripts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?
$COLOR_BLACK = "\033[0;30m";
$COLOR_DARKGRAY = "\033[1;30m";
$COLOR_BLUE = "\033[0;34m";
$COLOR_LIGHTBLUE = "\033[1;34m";
$COLOR_GREEN = "\033[0;32m";
$COLOR_LIGHTGREEN = "\033[1;32m";
$COLOR_CYAN = "\033[0;36m";
$COLOR_LIGHTCYAN = "\033[1;36m";
$COLOR_RED = "\033[0;31m";
$COLOR_LIGHTRED = "\033[1;31m";
$COLOR_PURPLE = "\033[0;35m";
$COLOR_LIGHTPURPLE = "\033[1;35m";
$COLOR_BROWN = "\033[0;33m";
$COLOR_YELLOW = "\033[1;33m";
$COLOR_LIGHTGRAY = "\033[0;37m";
$COLOR_WHITE = "\033[1;37m";
$COLOR_DEFAULT = "\033[0;37m";
 
echo <<< EOT
One fish, 
two fish, 
{$COLOR_RED}red{$COLOR_DEFAULT} fish, 
{$COLOR_BLUE}blue{$COLOR_DEFAULT} fish.
 
EOT;
?>

The only gripe I have about this is that COLOR_DEFAULT it's the same colour as I have on by default in iTerm. Anyone know the escape code to make it actually revert to what it was before instead of just making an assumption about what color is being used?

Hide Commandline Input
One of the first things I looked up when I started this project today was how to hide user input from the command line. I sure as hell didn't want people typing their passwords for UWACE on screen and having it actually display.
It turns out you can do this by temporarily telling your TTY to stop echoing what you type. The command for this is "stty -echo" and can be re-enabled using "stty echo". Below is how I implemented as part of the AngelAccess class to meet my needs.

1
2
3
4
5
6
7
8
9
10
11
 function Prompt($prompt_text,$hide = false) {
     echo $prompt_text;
     $input = "";
     if ($hide) {
         $input = trim(`stty -echo;head -n1;stty echo`);
         echo "\n";
     } else {
         $input = trim(fgets(STDIN));
     }
     return $input;
 }

As a complete side note, thanks to a boot-camped installation of Windows 7 (or at least I'm fairly sure that's the culprit,) my Macbook Pro is now stuck on Digital Out. This means I can't use the internal speakers on my computer under Mac OS X. Well... what I should say is that I can't use them without some annoying tricks. If I plug in my headphones, then tell my mac to use the input jack for audio input, then my internal speakers appear under the output options and let me use them. The speakers then work perfectly fine. They also work fine under Windows 7. A direct side effect of digital out being stuck on is a read light emanating from the audio jack.

The problem is apparently fairly common, unfortunately the only confirmed fixes for it are sending it back to Apple or wiggling a toothpick around in the audio jack. I had absolutely no luck with the toothpick, or precision screwdriver, or pen cartridge, or paintbrush handle. If anyone knows how to fix this problem, I would love to know. Otherwise, I'm just going to take it into the Apple store in Rideau some time this week and hope they can fix the problem. I really don't want to have to send my Mac in during my first week at Velocity.

Tagged as: , , , , , 3 Comments
14Nov/090

Omegle Voyeur – Multiple Connections

In case you haven't read the post about all my projects, here's a description of what Omegle Voyeur is:

Omegle is a website where you are connected to a stranger for a chat. It is dominated mostly by trolls whose primary purpose is to coerce you into a cyber session and then switch genders or to make you lose the game. Talking to these people is a rather tiresome endeavour, but seeing exactly what happens in these conversations is interesting. Omegle Voyeur is a way of watching a conversation which you aren't part of. What Voyeur does is form two simultaneous connections and then pass the input of one to the output of the other. This sets you up as a conversation proxy, allowing you to watch. Currently, this is exclusively a "sit and watch" program. Later I intend to add functionality to add more than 2 people into a conversation, automatically name the participants so it will be obvious that there are more than 2 people in the conversation, and allow the ability to interfere (mute participants/say things yourself) with a conversation. This concept was spawned during discussion (read: boredom) at CCC Stage 2, 2009.

In terms of technology, Omegle Voyeur is primarily one big Javascript Prototype class. Prototype is a Javascript Framework which makes the creation and maintenance of classes, conversion of data into JSON for transfer, and sending AJAX requests much, much easier.

There's also a very small bit of code in php which is able to be so short because it uses the incredible program cUrl. cUrl is a command line utility for grabbing data from websites using their URL. libcurl facilititates the use of curl in php without having to write your own wrapper.

Below is some php code I use to make curl even easier than it already is. simple_get($url) will return the HTTP GET result from the url specified. simple_post works similarly, but delivers data using the payload.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
// Simple cUrl
// Simple get and post requests 
function simple_get($url) {
    $c = curl_init();
    curl_setopt($c, CURLOPT_URL, $url);
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($c);
    curl_close($c);
    return $result;
}
 
function simple_post($url,$payload) {
    $c = curl_init();
    curl_setopt($c, CURLOPT_URL, $url);
    curl_setopt($c, CURLOPT_POST, true);
    curl_setopt($c, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($c);
    curl_close($c);
    return $result;
}
?>

When I started working on this project today (well, I suppose that would be last night now... wonder if I'll see the sunrise) I figured it would be a good time to get used to using git, so I made a repository using github.
So far I'm enjoying git. Everything seems to act pretty much the way you'd expect to, and I already had to do a revert once I realized my logic was wrong for the way I was structuring my code.

You can see the github for Omegle Voyeur here: http://github.com/phleet/Omegle-Voyeur
Feel free to design your own stuff with the all the code there - just be sure to link back here, or to the github page.

In any case, the thing the majority of the people reading this are probably interested in are the result.
Things I've updated since last time are primarily aesthetic and behind the scenes, but I did add the ability to connect one person to more than one other person, and the connections don't have to be mutual. In the first 3 way conversation example, 1 can only speak to 2, 2 can only speak to 3 and 3 can only speak to 1. It leads to some rather confused people.

You can see the current running version here: Omegle Voyeur.
EDIT: It seems that after being posted on reddit, omegle has (manually?) IP blocked me. The source should still work, so feel free to try it out yourself.
You can go grab XAMPP to run it locally.
For the time being, you can view it here: Omegle Voyeur

A quick note on how I figured out the Omegle communication protocol.
The entire code governing the process is conveniently kept here: http://omegle.com/static/omegle.js?27
Unless you enjoy reading 1000s of characters on a single line, you can use the JS Beautifier to clean it up to a readable state.

12Nov/094

SPOJ Problem 2: Prime Generator (PRIME1)

Problem: Prime Generator

Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!

Concept
The idea behind every solution here (with some variation) is to generate all the prime numbers that could be factors of numbers up to the maximum endpoint 1 billion. That square root happens to be around 32000. Using this array, do a bounded Sieve of Eratosthenes only in the range requested. In languages like php and python, it turns out that it's more efficient to build an associative array and check if the index is set than it is to generate a huge boolean array.

Code

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/// PRIME1 - C++ (g++)
// AC Time: 2.52s
// NOTE: I am aware that the use of vector and set actually
//  makes this code run _slower_
// I used vector and set simply as a way of practicing STL
#include <iostream>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
 
int main() {
    vector<int> primes;
    primes.push_back(2);
 
    for (int i = 3; i < = 32000; i+=2) {
        bool isprime = true;
        int cap = sqrt(i) + 1;
 
        vector<int>::iterator p;
        for (p = primes.begin(); p != primes.end(); p++) {
            if (*p >= cap) break;
            if (i % *p == 0) {
                isprime = false;
                break;
            }
        }
        if (isprime) primes.push_back(i);
    }
 
    int T,N,M;
 
    cin >> T;
 
    for (int t = 0; t < T; t++) {
        if (t) cout << endl;
 
        cin >> M >> N;
        if (M < 2) M = 2;
 
        int cap = sqrt(N) + 1;
 
        set<int> notprime;
        notprime.clear();
 
        vector</int><int>::iterator p;
        for (p = primes.begin(); p != primes.end(); p++) {
 
            if (*p >= cap) break;
            int start;
 
            if (*p >= M) start = (*p)*2;
            else start = M + ((*p - M % *p) % *p);
 
            for (int j = start; j < = N; j += *p) {
                notprime.insert(j);
            }
        }
 
        for (int i = M; i <= N; i++) {
            if (notprime.count(i) == 0) {
                cout << i << endl;
            }
        }
 
    }
    return 0;
}

8Nov/090

SPOJ Problem 1

When I saw that Thor had done solutions to the first few problems of Project Euler in many many languages, I thought "Hey! That's a good idea!" but didn't want to copy exactly.

So instead I'm doing solutions to some problems on SPOJ.
SPOJ is an online judge system full of algorithmic problems. This is one of the things that Hanson Wang did to get as good as he is. The solutions I'll be providing here are going to be very simple problems, so don't expect any magic. The beautiful thing about SPOJ is the sheer number of languages it will judge. I figured this was the perfect playground to make sure my code worked in all the languages I try.

Problem: Life, the Universe, and Everything

Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.

Solutions - In order of frequency that I use the language

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
//TEST AC - CPP (g++)
#include <iostream>
using namespace std;
 
int main() {
	int n;
	while(1) {
		cin >> n;
		if (n == 42) break;
		cout << n << endl;
	}
	return 0;
}

C99

1
2
3
4
5
6
7
8
9
10
11
//TEST AC - (gcc C99)
#include <stdio.h>
int main() {
	int n;
	while(1) {
		scanf("%d",&n);
		if (n == 42) break;
		printf("%d\n",n);
	}
	return 0;
}

php

1
2
3
4
5
6
7
8
<?
//TEST AC - PHP
while(1) {
	fscanf(STDIN,"%d",$n);
	if ($n == 42) break;
	print "$n\n";
}
?>

Python

1
2
3
4
5
6
#TEST AC - Python
while 1:
	num = input()
	if (num == 42):
		break
	print num

Bash

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
# TEST AC - BASH
 
while true; do
	read n
	if [ $n -eq 42 ]; then
		break
	fi
	echo "$n"
done

Ruby

1
2
3
4
5
6
7
8
#TEST AC - Ruby
while 1
	n = gets.to_i
	if n == 42
		break
	end
	puts n
end

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//TEST AC - Java
import java.io.*;
import java.util.*;
 
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
 
		while(true) {
			int n = in.nextInt();
			if (n == 42) break;
			System.out.println(n);
		}
	}
}

Perl

1
2
3
4
5
6
7
8
9
#TEST AC - Perl
while (1)
{
	$n = <STDIN>;
	if ($n == 42) {
		last;
	}
	print $n
}

C#

1
2
3
4
5
6
7
8
9
10
11
12
//TEST AC - C# (gmcs + Mono)
using System;
class WelcomeCSS {
	static void Main() {
		while(true) {
			int n;
			n = int.Parse(Console.ReadLine());
			if (n == 42) break;
			Console.WriteLine(n);
		}
	}
}

GNU Pascal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{TEST AC - GPC Pascal}
 
program TEST;
 
var n:integer;
 
begin
	while true do
		begin
			readln(n);
			if n = 42 then begin
				break;
			end;
			writeln(n);
		end;
end.

You can see Thor's Project Euler solutions here: Derek Thurn's Website - Project Euler