Jan 30, 2009

Linux, Dual Head and Background Images

The other day I got a new monitor in the mail from NCIX (who I highly recommend if you haven't heard of them). I realized that having two monitors at my last job gave me much more productivity, but since I work at home now I should have two monitors here. That's my excuse and I'm sticking to it.

I wrote a post less than a year ago on how to get dual head going with Compiz Fusion and back then it was really really annoying. Since then we have the nvidia-glx-new package right in Ubuntu, so there's no more having to shut down X in order to install the driver. Awesome.

So yeah, all you have to do is plug in your monitor, have nvidia-glx-new installed (assuming you're running an Nvidia card, no clue how to do it with ATI), open System->Administration->Nvidia X Server Settings, click X Server Display Configuration and enable things in there. For me, I had to click Detect Displays and click the monitor that is disabled. I clicked Configure, selected TwinView and off it went, working perfectly.

There was one last small issue. My desktop background was centred :(. So half of it was on one screen and half was on the other. There are two real fixes for this. If you just want the same image on both sides, you right-click the desktop (in Ubuntu), go to "Change Desktop Background", and set Style to Tiled. Done!
If you want to have two different backgrounds, the easiest option is probably just to take your current image, add some space to the right of it and paste a new image there. Then save your huge image as a file and select that as your desktop background.

On another note, having two screens like this for web development is awesome. I can fit a browser window, two IM windows, GVim and two terminals all without overlapping. Maybe it's time to try a tiling window manager!

Jan 29, 2009

Another Use For Duct Tape


Stupid cat.

Jan 28, 2009

Win/Fail in Ruby

Very simple yet quite amusing:
def win
true
end

FAIL = nil
Put this somewhere in your Ruby code, and you'll be able to write:
if something == win
...
if something == FAIL
Originally I had it with a lowercase fail, but that might conflict with some library somewhere. Plus it is cooler if it is in all caps.

This was inspired by a tweet from Giles Bowkett.

Jan 27, 2009

OSWs + Profit == Ethical?

The other day I posted about OSWs (open source websites, I shortened it because I might be talking about this a lot) and what their feasibility would be.

I've been thinking about this further and have come up with more ideas. One major difference between a web app and a regular app is that web apps require hosting. You can't just slap it up on SourceForge and say you're set.
The problem is that hosting costs money. Under the assumption that your site actually starts getting traffic, I don't feel that it is really fair for you to have to foot the bill while lots of other people are using your site. Not only is it unfair, but quite unsustainable unless you have another job which rakes in the dough.

This got me thinking about revenue models. If you look at other free sites, the make money off things like advertising, market research, donations, merchandise, etc. For the first two you need a lot of traffic to begin with, so if you don't have something great to offer users then it isn't really a great platform. If you're targetting a niche market with your OSW, then you're out of luck here. Merchandise works if your site has a branding, like webcomics or unique online games like Kingdom of Loathing (KoL). But if you don't have this, you're left to rely on donations. While I'd like to think if I started a site I'd get enough donations to cover the costs, but I don't think that's a realistic assumption (KoL does support itself through donations, however it gives rewards to those who donate).

The idea I'm having for a site (I won't tell you about it yet...ooh suspense! and no, it is not porn) allows users to create their own content. Ultimately I'd like to provide the tools for creative and high quality content.
Although the site itself is free (as in freedom), the content itself may not be - that's up to the content creator to decide. Should they choose to, the content creators may restrict access to their content except to those other users who want to pay for it. A source of revenue for the site would be to take a percentage of the money that content producers receive when they charge for their content.

Here is where the question of ethics comes in. Since the site is open source, it may be the case that other users would want to contribute in some way to the site, be it through code or documentation or whatever. Is it wrong to make profits off of this? Suppose somebody comes up with an idea for a sweet feature and codes it in and gives it to me, and it shoots profits through the roof. Is this unfair to the person with the sweet idea?
My answer would be no, provided the contributors know that the site does make profits. In that case it is fair for them to either not contribute, or to request some sort of compensation - either through money, or through privileged services through the site, or something.

For those few of you who actually read this blog, what do you think? Is this fair, or am I sounding like a douche in a suit?

Jan 26, 2009

Ruby Array#to_hash

The number of times I've had to convert an array to a hash is amazing. And the sad thing is that the standard Ruby array doesn't have any simple way to do it! This is probably because there are a lot of ways you can convert an array to a hash.

Here's the way I do it a lot:
hash = Hash[*keys.zip(values).flatten]
This works, unless your values array has nested arrays in which case you're screwed. A better alternative is:
hash = keys.zip(values).inject({}) { |h, nvp| h[nvp[0]] = nvp[1]; h }
This handles nested arrays, but it makes Ruby elegance freaks cry. But that's not my problem, so let's go like this:
class Array
def to_hash
self.inject({}) { |h, nvp| h[nvp[0]] = nvp[1]; h }
end
end
Assuming that the array is in name-value pair format, this should work fine. So you have:
[ [:a, 5], [:b, "hello"] ].to_hash   # => {:a => 5, :b => "hello" }
There are probably problems with this, if you know of any please comment!

Jan 25, 2009

Open Source Websites?

I've had an interesting thought over the last little while. I've been thinking about a cool website to build (I'll write more about this in a later post once I get more shit together) and I'm hoping to release all the code for it under the GPL, with the exception of things like DB username/passwords and things like that.

A problem is that websites cost money. If they get popular, then that amount of money is not exactly trivial depending on how complex and bandwidth-intensive your site is. Some kind of revenue stream is important, unless you want to shell out cash from your pocket for your expenses. There are a few easy methods of gaining revenue like advertising and donations, however if I were a businessman I wouldn't want to rely on these too heavily (unless I was Google) as they aren't exactly reliable.

I had the interesting pleasure of hearing RMS speak yesterday at CUSEC. He defined three sort of groups in which you can put works and explained how copyright "should" (in RMS's definition of should) apply to these different things. The three groups were: tools, subjective works, and creative works. The first included things like software, and he stated that they all should be free. My idea for a site is a platform on top of which creative content is built, and according to Stallman this is a tool and should therefore be free. The second one I'll sorta gloss over because it doesn't really apply to my project, but it is things like news articles and blog posts and what-not. The third one is things like music, movies, or art. This, he states, should have some sort of copy protection to provide incentive for creators to create, but the length of the copyright should be quite limited to like 5-10 years. Therefore the content which the users of my site create is copyright-able.

This gives me another idea. While the code for my site would be open-source and anybody would be allowed to take it and use it however they choose, the content hosted on the site would not always be open-source - I would give the option for users to release their content to the public domain, which they may or not do. Content creators will then be able to restrict access to their works through payment, and a percentage of this payment would go to the site as a hosting fee or something1. However I could add something that say if they have a non-public-domain work, then if they leave it or something for a year it transfers to the public domain, something like that. Then other people would be able to take it and mess around with it and potentially make it better.

This type of site no longer requires the privacy of source code as a barrier to entry of competition, but instead relies on the built-up content base of the site. The way you would remain competitive is by constantly improving the quality of your content and your application.

But what would keep people from "stealing" your code? What if they take it and make a better product? Well that is where the GPL comes in. Suppose they "steal" my code and alter it to add a sweet feature or something. Since it is under the GPL, I can just take their source code and put the feature into my site.
There is always this risk that they will make a huge feature that makes the site so much better that they gain a huge user/content-base advantage over me in a short amount of time, but whatever. I'll take the risk.

Another question to ask is how well does the open-source model apply to websites? While the four freedoms still apply to these types of software, the value behind the software is quite different. In a content-based website, much of the value is in the content and not just in the application itself. Compare this to an application like OpenOffice, where the value of the program is in what it does for you as a tool - in the case of OpenOffice, it makes it easier to write documents.
I'm not saying that there is no value in making a website open source (it has done wonders for Wordpress), however there is less value in its use as a tool and therefore there is less applicability of open-source.

1 This has probably been done before, and I'm expecting to get like 5 comments with sites that are doing this.

Jan 23, 2009

Contexts in Vim

One of the things I really like about Vim is how I keep discovering more stuff all the time to help me write things faster.

There are several context-based commands in Vim which are not complete commands on their own, but when combined with a context they do something depending on the context you provide. For example, dw is the d command (for delete) and the context is w which means "go to the beginning of the next word", and the combination of the two means "delete to the beginning of the next word". I knew about this one for a while, and things like d$ which is "delete to the end of the line" (an easy mnemonic for remembering: think regexes). However not too long ago I discovered what t and f do. When you type ta where a is an arbitrary character, it moves you to the character before the next a in the current line. With fa it moves the cursor to the next a.

So I thought this was kinda cool, although at the time I figured the t command was pretty useless. But that was until I discovered that you can use these as contexts in combination with a context-based command. So going dt) means "delete everything up until the character before a )" which is extremely handy. No more going delete-delete-delete... You can also use T and F to go backwards, where t and f go forwards.

Then I started playing around more. One thing that always annoyed me about Vim was when I wanted to delete several lines. You can use dnd and it will delete n lines, and so I ended up having to count all the lines and then pressing the key. Really annoying. However the "go to line" command in Vim is nG which means "go to line n". This can be used as a context for a context based command. So if you type d20G, it means "delete all the lines between the one I am on and line 20, inclusive". This goes both directions too. Now we're talking productivity.

Heck, you can even go d/hello and it will delete everything between where you are and the next string in the file that matches "hello" will be deleted. Same goes for d?hello, except it goes backwards. And these are regexes by the way, so don't be afraid to stick fancier stuff in there. Although you might need to remember that u is "undo".

It never ceases to amaze me how much you can get done with so little.

PS: I only used the d command for this post, but you can also use y or c which are two other context-based commands. There might be more, I just can't remember them at the moment.

Jan 20, 2009

Crayon Physics

I stumbled across a game called Crayon Physics, which is a neat little game where you draw things with crayons and physics applies to them. You use this to solve puzzles.

While they don't have a Linux or Mac version, it works very well under Wine! The only problem I came across is when it is in fullscreen the resolution doesn't actually change on my monitor, however the game still only takes up 1024x768 pixels of space. Unfortunately where the stuff is being displayed doesn't match up with the clickable areas, so in order to click a button you need to click something like 200px to the right of where the button is displaying. Fortunately once you turn fullscreen off it works quite well.

If you like the game, I'd recommend buying it. It's only $20, and you support small game creators!

UPDATE: For added amusement, make sure you have a kitten near the screen while you are playing. They will go nuts trying to figure out where the ball went when it falls of the bottom of the screen.

Jan 15, 2009

Shrink your Pictures

There may come a time when you copy your images off your digital camera and realize that they are at some ridiculous dimension like 2000x1700, which is not really a nice size to be emailing to your friends and family.
It might be ok if you just have one to send, but when you have like 30, it is not so easy.

So here's a little something to shrink them all:
Dir.mkdir "small" unless File.exists?("small")

Dir.foreach(".") do |file|
next if file !~ /\.(jpg|png)$/i

puts "Shrinking #{file}"
`convert #{file} -resize "300x300>" small/#{file}`
end
This shrinks all the jpgs and pngs in a folder to a maximum of 300x300 while maintaining the aspect ratio. If the image is smaller, then it is not resized. It dumps all the images in a folder called small.

Or if you don't like Ruby, here it is in bash:
mkdir small
for i in $(ls | egrep -i "\.(jpg|png)$"); do
echo "Shrinking " $i
convert $i -resize "300x300>" small/$i
done
Now you can send your pictures to all your friends! Note that in order to use these, you'll need ImageMagick installed. As for doing this in Windows, I have no idea. A good bet might be to use RMagick and then use rubyscript2exe to make it work.

UPDATE: Suppose there are also some pictures that you want to rotate too. Luckily for us, ImageMagick handles this too. Unfortunately I don't know bash well enough to update the bash one, but for Ruby:
Dir.mkdir "small" unless File.exists?("small")

Dir.foreach(".") do |file|
next if file !~ /\.(jpg|png)$/i

out_file = ""
commands = ""

if file =~ /^rotate(\d+)_/
commands += "-rotate \"#{$1}\" "
out_file = file[/_(.*)$/, 1]
end

puts "Shrinking #{file} to small/#{out_file}"
`convert #{file} -resize "300x300>" #{commands} small/#{out_file}`
end
Now if you prefix any files you want to rotate with "rotateX_", it will rotate your files clockwise by X degrees. I'd recommend using 90.
It's great with any file browser that shows the thumbnails of the image, so you can just look, rename (by pressing F2 in Nautilus) and go.

This is also pretty easy to add on to if you want to add more filters. ImageMagick has a lot of stuff it can do - you can even make things into polaroids if you want.

Jan 12, 2009

Ethanol: Good or Bad?

I passed by the gas station earlier today and they had a big sign up saying something like, "Save the world! Use ethanol fuel!" It made me wonder, does ethanol fuel actually help the environment? I decided this is the subject of a slightly scientific inquiry (by slightly scientific I mean not very scientific, but whatever).

First off, let's take a rate of increase of CO2 in the atmosphere, r. If ethanol burns cleaner than gasoline (according to Wikipedia it does) then there will be a decrease in r: Δr1 < 0. However since it is not pure ethanol being burned and simply an additive to gasoline, Δr1 would not be as large as it would be if it were pure ethanol being burned.
So from this first glance, ethanol is good for the environment (assuming a reduction in the r is good). However let's dig into the economics a little bit. If ethanol burns cleaner than gasoline and the price isn't that high in comparison, it will increase demand for ethanol. This is a demand shift, which results in an increase in both the equilibrium price and quantity. So price of ethanol increases. This now causes an increase in supply, because ethanol is now more profitable. This causes an increase in demand for the inputs of ethanol, which at this point in time is mainly corn. So the price of corn will increase too.

There are many effects of an increase in the price of corn, two of which I will look at. The first is that the quantity supplied will increase. This requires more land to grow the corn on. While a good chunk of this is done in the US and the EU from subsidized farmers, another good chunk is done in Brazil and other places where there is a lot of forest. The forest gets cut down to make room for cornfields. Since forest is one of the big things that reduces CO2 in the air, we will end up increasing r by chopping down forest: Δr2 > 0. This is probably not a big number, but is there nonetheless and changes the net effect on r.
Another effect is, well the increase of price in corn. How many people eat corn worldwide? Also an increase in the price of corn will increase the price of corn alternatives (price of corn increases, people want to buy alternatives, increase in demand for alternatives, increase price of alternatives). That will impact people who don't even eat corn!
This second effect is why I find that people who want to both save the rainforest and save the starving kids in Africa can't really get both of what they want. Due to scarcity, these two causes are often at odds with one another. We can make things better for the environment, at the cost of social welfare, or we can increase social welfare at the cost of the environment.

One more thing to look at is something like moral hazard. Here is where incentives come in. The issue here is that since ethanol burns cleaner, people may feel less guilty about driving. So they drive more, offsetting some reduction in r that they may have added by using ethanol instead of pure gasoline. It may or may not be a concern, but it is still something to think about. So this means that Δr1 is larger (read: less negative) than we originally thought above and could even be positive.

Let's take a look: net effect Δr = ΣΔri
Since all the changes could be positive, it is possible that the net effect could be positive. However making a guess at the values of the Δrs, I'll say that the net effect is negative, but not that negative. Using ethanol may reduce r, but it is not as much as you would think from an initial look at the problem. Furthermore it may not actually make r negative, which would be necessary to offset any damage humanity may have done.

Jan 8, 2009

Mongrel as a Library, not a Server

Most people who have done any Rails coding have at least heard of Mongrel, which is a widely-used web server for hosting Ruby web applications. Usually it is done with Rails, but I've been using it with Merb and it supposedly works with a number of frameworks.

One thing that is cool about Mongrel is that it is not really just a web server, rather a library for developing web servers. For example, the way Rails works with Mongrel is just a class called RailsHandler that inherits from Mongrel::HttpHandler, which then calls the appropriate controller from your class. The mongrel_rails script is just something that sets up the Rails environment and starts the server.

Suppose you wanted to write an application (notice it is not necessarily a web application, but could be) that could use HTTP to talk to other apps. You want something simple, you don't need Rails or any other framework to do anything for you. You can use Mongrel for this.

Here's some code:
# note that I grabbed some of this code from Mongrel's RDoc
require 'rubygems'
require 'mongrel'

class MyAwesomeHandler < Mongrel::HttpHandler
def process(request, response)
response.start(200) do |head, out|
head["Content-Type"] = "text/plain"
out.write("hi!\n")
end
end
end

server = Mongrel::HttpServer.new("0.0.0.0", 3000)

server.register("/", MyAwesomeHandler.new)

server_thread = server.run

# do your app logic here

server_thread.join
Make sure the mongrel gem is installed, and run this code. Go to your browser and type 'http://localhost:3000' and what you should see is a simple string that says "hi!".

So how does this work? It's pretty simple really. We create a class that handles an HTTP request. It has a process() method that gets two objects, the request info (contains any params passed) and the response info (the object that lets you respond). We then say we're doing plain text, and spit out a "hi!".
Outside the class we create an instance of the HTTP server with the HttpServer class (whoda thunk...), bind any requests to / to our awesome handler, and fire that server up. The run() method returns a thread object, which we can then treat as a regular old Ruby thread. At the end of the app, we join the thread to wait for it to finish (it never finishes, unless you press Ctrl+C).

So we haven't really created a web server here. Instead we've created an application that is capable of using HTTP to communicate (a web server is an example of an application that does this). Between the server.run and server_thread.join lines, you can do whatever you want, and the server thread just sits around waiting for any request to come in. In fact, you can store your own Ruby objects on your side and so long as you're coding in a thread-safe manner, you don't need memcached or a database to keep things! Pretty cool!

Jan 7, 2009

How to Learn Linux - Part I

The first step to learning Linux is actually installing it. I'll assume you're coming from Windows, mainly because I haven't used a Mac in about 8-9 years and things have changed with them since then. And if you're using something besides Windows, Mac or Linux, you probably don't need my help with anything!

There are some pre-requisites to installing it yourself, as there would be with installing any operating system: you need some computer know-how. You need to know things like what a hard-drive is. Same for drivers, although installing drivers is quite a different thing in Linux than in Windows.
You also need a desire to do it. Maybe it is curiosity about Linux itself, or maybe it is a desire to learn about it in order to do a job that uses Linux a lot like a network/systems admin.
The desire can't really be, "I'll learn Linux because it is the next big thing!" No, Linux is not the next big thing. I don't think you'll be able to make millions through Linux. Linux has this whole open-source thing going that sees ownership and property as damage, and routes its way around it. People have not been successful at selling Linux (at least not by selling it directly), and I highly doubt you will too.

One thing keeping many geeks away from Linux is the hassle of actually installing it. Usually you have to create a new partition (and therefore running the risk that something will mess up and you'll lose a ton of data - been there, done that), and then actually installing the system. Then if the install messes up after it's tweaked the master boot record, you're up shit creek without a paddle if you don't know what to do now.

You can do it this way. It's the way I did it when I first got into Linux. Fortunately I didn't have any problems getting it installed, and chances are you won't either. But there's still a risk.

There are easier and less risky ways to do it. Ubuntu has this thing called Wubi, which I think in theory is a great idea. I've never used it before since I was using Ubuntu before Wubi came out, so I don't know how well it works in practice. Feel free to tinker with it.

The way I think is good is through virtualization. This involves installing some software like VMware or VirtualBox which are programs that allow you to install other operating systems inside them, and they function kinda like a sandbox. You can interact with the system as though it were your system, but it can't access the rest of your system.
The benefit of this over Wubi is that you're not limited to Ubuntu (correct me if I'm wrong, but I think Wubi is only for Ubuntu unless you do some serious mucking). You download an ISO file (CD image) of whatever distribution you like, and install away. IMO the best newbie one is Ubuntu, but some other good ones are Fedora (a variant of the popular Red Hat Linux) and Mandriva (formerly Mandrake). I first used Linux with Mandrake several years ago, and then used Fedora when it came out - that was version 1, they're on version 10 now, wow! Another one I liked but isn't quite as newbie friendly is openSUSE (not sure how to pronounce that one, is it open-soo-see? open-soos?). Finally one that I've used that is very much not newbie friendly but a lot of people like is Gentoo, which is good if you want complete control and customizability of your system.