tag:blogger.com,1999:blog-34315043443288028972024-02-08T05:16:47.383-08:00Trail of CodingAnonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.comBlogger37125tag:blogger.com,1999:blog-3431504344328802897.post-80166728205986239412013-09-29T19:22:00.000-07:002013-09-29T19:22:36.813-07:00Sorting QuicklyMerge sort and heap sort both run in O(nlgn), which is where the lower limit lies in comparison sort algorithms.<br />
<br />
Merge sort is intuitive and fairly straightforward. Heap sort has the advantage of being able to be used in priority queues efficiently.<br />
<br />
Then there is quick sort. Quick sort also runs in O(nlgn), but only for its average and best case scenarios. In the worst case, quick sort runs in O(n^2). However, quick sort is preferred over merge sort and heap sort. Why? Because other than the worst case, quick sort runs faster in practice due to its tighter loops. But what about the worst case? The good news is that there is only 1 worst case sequence, which is if at each iteration, we choose the largest number as the pivot. If we use a randomized algorithm of quick sort, the chances of hitting the worst case is 1/n!, which is very low. Hence, in practice, it's worth the risk of hitting the worst case.<br />
<br />
Here's my code for quick sort and a test file.<br />
<a href="https://gist.github.com/wmwong/6758508#file-quicksort-rb">https://gist.github.com/wmwong/6758508#file-quicksort-rb</a><br />
<a href="https://gist.github.com/wmwong/6758508#file-quicksort_test-rb">https://gist.github.com/wmwong/6758508#file-quicksort_test-rb</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-43837654919502190892013-09-28T15:06:00.001-07:002013-09-28T15:06:18.444-07:00Fun with Heaps!It's been a while since my undergraduate and I've forgotten how fun my Computer Science degree was.<br />
<br />
I'm re-reading <a href="http://mitpress.mit.edu/books/introduction-algorithms">Introduction to Algorithms</a> and having quite a lot of fun with it.<br />
<br />
The latest chapter I went over was the chapter on heaps. So I decided to implement some of the data structures and algorithms.<br />
<br />
Here is my code for creating heaps (both max and min-heaps) and heap sort.<br />
<a href="https://gist.github.com/wmwong/6747122#file-heap-rb">https://gist.github.com/wmwong/6747122#file-heap-rb</a><br />
<br />
I also created a test file.<br />
<a href="https://gist.github.com/wmwong/6747122#file-heap_test-rb">https://gist.github.com/wmwong/6747122#file-heap_test-rb</a><br />
<br />
Also introduced along with heaps are priority queues as they go really well together. Here are my implementations for a max and min-priority queue.<br />
<a href="https://gist.github.com/wmwong/6747122#file-priority_queue-rb">https://gist.github.com/wmwong/6747122#file-priority_queue-rb</a><br />
<br />
And of courses tests!<br />
<a href="https://gist.github.com/wmwong/6747122#file-priority_queue_test-rb">https://gist.github.com/wmwong/6747122#file-priority_queue_test-rb</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-89885761135468539592013-09-27T10:00:00.000-07:002013-09-27T10:00:00.644-07:00Code Kata 6: AnagramsFor this one, we get to play with anagrams! Anagrams are words with the same letters. An example is "read" and "dear".<br />
<br />
The task is to take a list of words and find all the anagrams in the list.<br />
<a href="http://codekata.pragprog.com/2007/01/kata_six_anagra.html">http://codekata.pragprog.com/2007/01/kata_six_anagra.html</a><br />
<br />
Being honest, I have to tell you that I originally misread the task. I thought that I was supposed to generate all possible anagrams for each word in the list. Instead, you're supposed to find all words that are anagrams within the list. More on my folly later.<br />
<br />
For this task, the link to the word list is broken. I happened to find it after Googling, so I included it in my Gist.<br />
<a href="https://gist.github.com/wmwong/6724712#file-wordlist-txt">https://gist.github.com/wmwong/6724712#file-wordlist-txt</a><br />
<br />
My solution was fairly simple. I used a hash function which basically took each word and sorted the letters in alphabetical order. I then used the sorted word as the key to my hash and stored the original word as the value. Because of the nature of anagrams, all words that are anagrams of each other will generate the same sorted word.<br />
<a href="https://gist.github.com/wmwong/6724712#file-6_anagrams-rb">https://gist.github.com/wmwong/6724712#file-6_anagrams-rb</a><br />
<br />
There is one issue with this solution though. It is not optimal. We need to sort each word. If we let n be the number of words, and m be the average number of letters in a word, our running time is O(nmlogm) if we use merge sort.<br />
<br />
I cannot take credit for coming up with a better solution, but I will share it here. There is a theorem called the <a href="http://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic">Fundamental theorem of arithmetic</a>. This gives rise to two things: that all integers greater than 1 can be represented as a product of primes and that those primes are always the same (although you can order them any way you like).<br />
<br />
How does this help us? Well, that means we can assign each letter in the alphabet a unique prime number. When we get a word, we take each letter, map it to its prime number, and multiply it all together. This generates a unique integer. In order to get the same integer, you must multiply the same set of primes, which maps to the same set of letters, which means we found an anagram! What's more important is that this hash function takes O(m), which was better than our hash function based on sorting which was O(mlogm).<br />
<br />
With this new hash function, that brings the algorithm to O(nm) which is an improvement over O(nmlogm). In reality though, m could probably be considered a constant because the average length of a word doesn't really change and so either solution would be just as good.<br />
<br />
I didn't write example code for this as the code is straight forward.<br />
<br />
Instead, I'll dive into what I thought was the task.<br />
<br />
After reading the task, I thought that we were given a list of words, and for each word, we were to find all anagrams of that word. This task was actually harder than the original task as I had to generate possible anagrams of a word and then check them against a dictionary.<br />
<br />
Here is my solution to this task. I stopped after I noticed I was working on the wrong task so it's not fully thought through. My first attempt tries to reduce the number of permutations checked by disregarding duplicate letters. Further optimizations could be made by memoizing each set of letters we come across. This also does not massage the word to only contain alphanumeric characters, so this solution may not be 100% correct.<br />
<a href="https://gist.github.com/wmwong/6724712#file-6_anagram-rb">https://gist.github.com/wmwong/6724712#file-6_anagram-rb</a><br />
<br />
And here is the test file I used to check the solution.<br />
<a href="https://gist.github.com/wmwong/6724712#file-6_anagram_test-rb">https://gist.github.com/wmwong/6724712#file-6_anagram_test-rb</a><br />
<br />
Lastly, here is the file I used to run the small example given in Code Kata 6. This is where I found out my list looked different than his, and that I was actually solving the wrong task.<br />
<a href="https://gist.github.com/wmwong/6724712#file-6_anagram_generator-rb">https://gist.github.com/wmwong/6724712#file-6_anagram_generator-rb</a><br />
<br />Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com1tag:blogger.com,1999:blog-3431504344328802897.post-6664081878629930512013-09-25T10:00:00.000-07:002013-09-25T10:00:02.401-07:00Code Kata 5: Bloom FiltersIn this one, we learn about bloom filters and implement a spell checker.<br />
<a href="http://codekata.pragprog.com/2007/01/kata_five_bloom.html">http://codekata.pragprog.com/2007/01/kata_five_bloom.html</a><br />
<br />
Here's my version.<br />
<a href="https://gist.github.com/wmwong/6695303">https://gist.github.com/wmwong/6695303</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-31537797294372664372013-09-23T22:09:00.000-07:002013-09-23T22:09:49.497-07:00Code Kata 4: Data MungingThis one is about reading data from a file and retrieving relevant data.<br />
<a href="http://codekata.pragprog.com/2007/01/kata_four_data_.html">http://codekata.pragprog.com/2007/01/kata_four_data_.html</a><br />
<h2>
Solutions</h2>
<ul>
<li><a href="https://gist.github.com/wmwong/6679717#file-4_weather-rb">Part One: Weather Data</a></li>
<li><a href="https://gist.github.com/wmwong/6679717#file-4_football-rb">Part Two: Football Data</a></li>
<li><a href="https://gist.github.com/wmwong/6679717#file-4_dry-rb">Part Three: DRY</a></li>
</ul>
<h2>
Kata Questions</h2>
<div>
<ul>
<li>Deciding to use regular expressions made the refactoring much more easy.</li>
<li>When I wrote the second program, I definitely followed many of the things I did in the first program. This made refactoring much more easy too.</li>
<li>Refactoring code to rip out common code is usually a good practice. This helps in maintainability especially when you have to change the piece of code. If it wasn't refactored, you would have to change the code in two different places and test them separately. It also becomes a candidate for reuse when you come across the same scenario. If done right, it helps with readability because it breaks code into smaller chunks. This way, you can hold less in your head. There is, however, one scenario where I find refactoring out common code is a downfall: when future requirements cause slight differences in the common code. Because we don't know all the cases we will ever handle when we refactor out common code, it is hard to account for this. However, there have been several times where future changes cause slight differences in the common code and it turned out that refactoring was a bad idea.</li>
</ul>
</div>
Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-62880786643513516582013-09-23T09:59:00.000-07:002013-09-23T09:59:00.030-07:00Code Kata 3: How Big, How Fast?This one helps you quickly estimate sizes and speed.<br />
<a href="http://codekata.pragprog.com/2007/01/kata_three_how_.html">http://codekata.pragprog.com/2007/01/kata_three_how_.html</a><br />
<h2>
How Big?</h2>
<div>
<h3>
How many bits?</h3>
For this one, the way I thought about it is that 10 bits is roughly 1000 (2^10).</div>
<div>
11 bits gives you roughly 2000 (2^11).</div>
<div>
A pattern emerges as such: 2000 = 1000 * 2 ~ 2^10 * 2^1 = 2^(10+1).</div>
<div>
Hence, you can quickly figure out a rough approximation by seeing how many multiples of 1000 there are and then figure out the leftovers.</div>
<div>
<ul>
<li>1,000 ~ 2^10</li>
<li>1,000,000 ~ 2^20</li>
<li>1,000,000,000 ~ 2^30</li>
<li>1,000,000,000,000 ~ 2^40</li>
<li>8,000,000,000,000 = 1,000,000,000,000 * 8 ~ 2^40 * 2^3 = 2^43</li>
</ul>
<div>
<br /></div>
<h3>
How much space?</h3>
<div>
For a town of 20,000 residences, to store their names, addresses, and phone numbers, we can assume that we need about 200 characters per resident. This gives us 20,000 * 200 which is 4,000,000 characters. If each character takes up a byte, then we end up with roughly 4MB of data.</div>
</div>
<div>
<br /></div>
<h3>
Binary trees!</h3>
<div>
Storing 1,000,000 integers in a binary tree will require 1,000,000 nodes. In the best case (balanced), the number of levels will be log2(1,000,000). Using our approximation technique from above, that would be roughly 20 levels. Any worse then a balanced tree would have more levels up to 1,000,000 levels. The space required to hold a tree like this would be calculated by noticing what data each node needs to hold. Each node needs to hold its own value, a pointer to the left child, and a pointer to the right child. If each piece of data requires 32 bits (4 bytes), then each node requires 12 bytes. This totals 12,000,000 bytes or 12MB of data.</div>
<h2>
How fast?</h2>
<h3>
How long?</h3>
<div>
Assuming that each page in the book has roughly 200 characters. Each character takes up a byte. This means we have roughly 240,000 bytes to send. A 56kb/s modem translates to a 7,000B/s modem. This means it would take roughly 350 seconds which is roughly 6 minutes.</div>
<div>
<br /></div>
<h3>
Binary search!</h3>
<div>
It takes 4.5mS to search 10,000 entries and 6mS to search 100,000. There is 10x more to search and it was done in 1.5mS more time. Hence, for 10,000,000, it should take roughly 9mS.</div>
<div>
<br /></div>
<h3>
Brute force</h3>
<div>
There are 96^16 possible passwords.</div>
<div>
A rough estimation would be 100^16 = (10^2)^16 = 10^32.</div>
<div>
Since we can do 1000 searches per second, this would take 10^32 / 10^3 = 10^29 seconds to perform.</div>
<div>
There are 86,400 seconds in a day which is roughly 100,000 seconds. This gives us 10^24 days.</div>
<div>
Dividing by 365 is a little hard to do but dividing by 1000 is "close enough". This gives us 10^21 years.</div>
<div>
Brute force is definitely not a viable approach.</div>
Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-56062403662300836692013-09-22T12:56:00.001-07:002013-09-22T12:59:23.900-07:00Code Kata 2: Karate ChopThis kata challenges you to implement binary search in 5 different ways and to document things you had trouble with, like "off by one errors" and fencepost errors.<br />
<a href="http://codekata.pragprog.com/2007/01/kata_two_karate.html">http://codekata.pragprog.com/2007/01/kata_two_karate.html</a><br />
<br />
Here are my attempts in Ruby.<br />
<a href="https://gist.github.com/wmwong/6662429">https://gist.github.com/wmwong/6662429</a><br />
<br />
Got any other ideas on how else to solve this? Or feedback for my code? Let me know down below in the comments!Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-33104301752177039082013-09-22T12:51:00.003-07:002013-09-22T12:58:36.544-07:00RustyOver the years, I've been working on several different products, all of which has allowed me to practice building products and shipping code. However, I haven't had much time to experiment and play. I feel I've lost many things that I've learnt from my CS degree.<br />
<br />
So starting from today, I will start practising and learning again.<br />
<br />
To start off, I'm going to work my way through <a href="http://codekata.pragprog.com/">Code Kata</a>. I'll be posting my solutions on <a href="https://gist.github.com/">Gist</a>.<br />
<br />
I also plan on going through my <a href="http://mitpress.mit.edu/books/introduction-algorithms">Introduction to Algorithms</a> book again. I'll try to summarize what I learn as I go.<br />
<br />
Well, time to get started!Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-37750700154458068892013-02-21T10:12:00.000-08:002013-02-23T15:37:44.231-08:00Ubuntu: Out of Disk Space<h2>Problem</h2>When I first installed Ubuntu on my desktop, I had decided I would like to partition my /home directory from the rest of my filesystem. This way, if an Ubuntu upgrade fails, I can always perform a clean install without having to backup my data. Or, theoretically, I could install another OS and my data would all still be there. When I partitioned the / directory, I decided that 10 GB should be enough.<br />
<br />
Well, recently, I've been hitting up against that 10 GB limit. Every day when I boot up my computer, I get a warning that I only have a few hundred MB of space left. Well, today, I'm at 100% usage. I couldn't even send an email out from Thunderbird.<br />
<br />
So, I tried clearing space. I tried running<br />
<pre class="prettyprint lang-bsh">sudo apt-get autoremove</pre><br />
Unfortunately, there was nothing left to autoremove.<br />
<br />
I then browsed through /usr/local as that's where I store any applications I need to compile and run. Again, nothing extra to remove.<br />
<br />
My last resort was heading to /tmp to clear anything there. However, it didn't make much of a difference.<br />
<br />
I was still stuck.<br />
<br />
<h2>Solution</h2>Suddenly, a thought came to me. I've gone through several Ubuntu updates where it installed Linux kernel headers. Maybe that's what was taking up space. After a quick Google search, I came upon a post that would delete all unused Linux headers.<br />
<br />
Just to be safe, before running this, restart your machine.<br />
<pre class="prettyprint lang-bsh">dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge</pre><br />
This ran in the terminal for some time while it cleaned out all my unused Linux kernel headers. I ended up getting rid of 3 GB of data.<br />
<br />
I was free again!<br />
<br />
So next time you're running out of room, make sure it isn't some old Linux headers taking up space.<br />
<br />
<h2>References</h2><a href="http://ubuntugenius.wordpress.com/2011/01/08/ubuntu-cleanup-how-to-remove-all-unused-linux-kernel-headers-images-and-modules/">http://ubuntugenius.wordpress.com/2011/01/08/ubuntu-cleanup-how-to-remove-all-unused-linux-kernel-headers-images-and-modules/</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-10593995722872174182012-08-19T10:00:00.000-07:002012-08-19T10:00:02.292-07:00Ubuntu 12.04: No Root File System Is Defined<h2>Problem</h2>I got this error when trying to do a fresh install of Ubuntu 12.04 from USB. I get past the screen that asks if you want to download updates and install third party software, then I get stuck on the "Installation Type" screen.<br />
<br />
The installer only sees /dev/sdb which is my USB and shows nothing in the partitions table. All the buttons are disabled. Clicking continue gives me the error "No root file system is defined".<br />
<br />
Instead of installing, I went to "Try Ubuntu". This loaded up the Ubuntu desktop. Checking gparted and fdisk, I was able to find /dev/sda. Great! Unfortunately, trying to install gives me the exact same problem.<br />
<br />
<h2>Solution</h2>When you "Try Ubuntu", open up a terminal and type<br />
<pre class="prettyprint lang-bsh">sudo apt-get remove dmraid -y</pre>It gave me some errors, but I ignored them. I ran the installer from the desktop and voila! The installer sees /dev/sda and I could install Ubuntu 12.04<br />
<br />
<h2>References</h2><a href="http://askubuntu.com/questions/111926/installation-stuck-on-installation-type-screen">http://askubuntu.com/questions/111926/installation-stuck-on-installation-type-screen</a><br />
Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-68134564314399365372012-07-16T10:00:00.000-07:002012-07-16T10:00:00.438-07:00Ubuntu: Automating Locking and Suspending<h2>Locking and Suspending from the Terminal</h2>The first thing to note is that suspending the computer does not lock the computer. They are separate actions.<br />
<br />
To lock the screen.<br />
<pre class="prettyprint lang-bsh">gnome-screensaver-command --lock</pre><br />
To suspend the computer, check out this article on <a href="http://www.absolutelytech.com/2010/10/17/howto-suspend-ubuntu-from-terminal-or-keyboard-shortcuts/">How To Suspend Ubuntu from the Terminal</a>. If you're simply running this from the terminal either by typing or using a script, I would suggest method 3 as it does not require sudo.<br />
<pre class="prettyprint lang-bsh">gnome-screensaver-command --lock
dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Suspend
</pre><br />
<h2>Locking and Suspending from cron (Problems)</h2>Note: If you don't care about the problems and just want the solution, skip down to the next section.<br />
<br />
If you had the above in a script that you could run from the terminal, it follows that you could run this script from a cron. Perhaps the scenario is that you wanted to lock down and suspend a particular computer at work every day at 5pm.<br />
<br />
The script would look like this.<br />
<pre class="prettyprint lang-bsh">#!/bin/sh
gnome-screensaver-command --lock
dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Suspend
</pre><br />
Let's say it was stored in ~/bin/lock-suspend.sh. Remember to make sure that it's executable.<br />
<pre class="prettyprint lang-bsh">chmod +x ~/bin/lock-suspend.sh
</pre><br />
When you run this in the terminal, your computer locks and suspends. Everything is fine.<br />
<br />
Next, you would edit your crontab.<br />
<pre class="prettyprint lang-bsh">crontab -e
</pre><br />
And place the following in it. The output from standard out and error is logged to a log file.<br />
<pre class="prettyprint lang-bsh">0 5 * * * /home/user/bin/lock-suspend.sh > /home/user/logs/lock-suspend.log 2>&1
</pre><br />
You then wait for 5pm to come around and lo-and-behold, nothing happens.<br />
<br />
Knowing that cron logs to /var/syslog/log, you go and check it and find that the cron job ran, but an error occurred.<br />
<br />
Since the script was logged to /home/user/log/lock-suspend.log, you check it out and find the following errors.<br />
<pre class="prettyprint lang-bsh">** Message: Failed to get session bus: Command line `dbus-launch --autolaunch=364dc0936e296ffa0881a3e90000000a --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n
Error org.freedesktop.UPower.GeneralError: not authorized
</pre><br />
What does this mean? <br />
<br />
After much Googling, I came across this <a href="http://ubuntuforums.org/showthread.php?t=632580">thread</a>. It explained that the first message came about because cron does not have access to the same environment as the terminal. More specifically, it is missing the environment variable DBUS_SESSION_BUS_ADDRESS.<br />
<br />
I did not look much further into the second error though. I assume it is because cron does not have access to the dbus. This was easily solvable though as there are several methods to suspend, for instance method 2.<br />
<pre class="prettyprint lang-bsh">sudo pm-suspend
</pre><br />
<h2>Locking and Suspend from cron (Solution)</h2>In order to solve the first problem, we need to figure out what should go into the environment variable DBUS_SESSION_BUS_ADDRESS.<br />
<br />
When you first login, DBUS_SESSION_BUS_ADDRESS is set for you. We can grab this and write it to file. Add the following to your .bashrc file.<br />
<pre class="prettyprint lang-bsh">set | grep DBUS_SESSION_BUS_ADDRESS > ~/.DBUS_temp
</pre><br />
Now we need to modify the lock-suspend.sh script. However, before we do that, we need to think about the solution to the second problem. Since we'll be using sudo to run pm-suspend, the cron job must be run as root instead of as the current user. We will need to modify the script expecting root to be running the script.<br />
<br />
Note that in order to set the DBUS_SESSION_BUS_ADDRESS environment variable, we use source. However, in order to use source, we must use bash instead of sh.<br />
<br />
The full script.<br />
<pre class="prettyprint lang-bsh">#!/bin/bash
source /home/user/.DBUS_temp
export DBUS_SESSION_BUS_ADDRESS
su -c "gnome-screensaver-command --lock" user
/usr/sbin/pm-suspend
</pre><br />
Now modify the root's crontab.<br />
<pre class="prettyprint lang-bsh">sudo crontab -e
</pre><br />
And add the following.<br />
<pre class="prettyprint lang-bsh">0 5 * * * /home/user/bin/lock-suspend.sh > /home/user/log/lock-suspend.log 2>&1
</pre><br />
Come 5pm, the computer locks and suspends gracefully and you can relax knowing that your data is safe and you're saving the planet by reducing power usage.Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com1tag:blogger.com,1999:blog-3431504344328802897.post-86140600439409423062012-03-08T10:00:00.000-08:002012-07-15T22:10:47.494-07:00SSH Key FingerprintingAfter <a href="http://www.extremetech.com/computing/120981-github-hacked-millions-of-projects-at-risk-of-being-modified-or-deleted">GitHub got hacked</a>, I received an email informing me that my SSH keys may have been compromised. I needed to login to GitHub and confirm each SSH key.<br />
<br />
The thing is, the SSH keys were being shown using their fingerprints. I've seen this before when logging into a server through SSH, but I've never actually had to generate one before.<br />
<br />
Thank goodness for Google. Here's how.<br />
<pre class="prettyprint lang-bsh">ssh-keygen -lf <keyfile>
</keyfile></pre><br />
<h2>References</h2><ul><li><a href="http://www.lysium.de/blog/index.php?/archives/186-How-to-get-ssh-server-fingerprint-information.html">SSH fingerprinting</a></li>
</ul>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-19911906403191745392011-09-16T10:00:00.000-07:002011-09-16T10:00:01.195-07:00Ubuntu: Install from USBApparently, you can install Ubuntu through a USB stick if your BIOS can boot from USB. I though this was pretty neat and wouldn't have to deal with throwaway media like CDs and DVDs. Unfortunately, each time I tried, the computer would not boot from the USB. It just kept booting from the harddrive no matter what I did in the BIOS.<br />
<br />
I finally managed to figure this one out. The first 2 computers just didn't boot from USB. No hints. Nothing. Googling this problem brought up nothing. The solutions were to re-download Ubuntu, check your USB, use a CD, try on another computer, etc. <br />
<br />
Fortunately, the 3rd computer I used gave me "Missing Operating System". Bingo! I found something searchable. This brought up a nice blog article. A solution! And it works! Basically, the problem was in the creation of the bootable USB. I was using Ubuntu's Startup Disk Creator. Apparently, it doesn't properly wipe out the USB and repartition appropriately. This caused havoc. The idea is to wipe out the USB stick and repartition before using Startup Disk Creator. This solved my problem.<br />
<br />
Check out the solution here: <a href="http://ubuntuliving.blogspot.com/2008/11/missing-operating-system-step-by-step.html">http://ubuntuliving.blogspot.com/2008/11/missing-operating-system-step-by-step.html</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-64125932492171463002011-09-02T10:00:00.000-07:002011-09-02T10:00:05.224-07:00Ubuntu + iPhone: Upgrade/RestoreIt's no secret. Ubuntu + iPhone is a pain in the ass! However, it just got a little less painful for me. <br />
<br />
You see, the way I've been approaching this is to never plug my iPhone into my computer. If the two don't meet, there can't be any problems. Don't solve your problems. Get rid of them!<br />
<br />
Unfortunately, I've been losing reception the last two weeks and it's been annoying me to no end. I called my service provider and they determined it's probably because I'm still on 3.1.3. Great. I need to upgrade my iPhone. iPhone, meet Ubuntu. Ubuntu, meet iPhone. Now PLEASE play nice.<br />
<br />
Of course, that was too much to ask for. I installed VirtualBox and got Windows XP installed. I then added the iPhone as a USB connection in the settings. I then proceeded to plug in my iPhone. iTunes detects my iPhone. Yay! A small triumph. I decided to restore instead of upgrade. I wanted to start from scratch anyways.<br />
<br />
After iTunes wiped out my data, it started to prepare for the restore. At which it hung. After a few minutes, it gave me a 1602 error. I tried everything I could think of: reboot iPhone, reboot VirtualBox, reboot Ubuntu, re-plug in iPhone, etc. The best I got out of all this was a different error: 1604. At this point, my iPhone is permanently in Recovery Mode and now, I couldn't even select the iPhone USB connection in VirtualBox.<br />
<br />
I thought to myself, "Screw this. I'm fixing you even if it takes all night!" And so, I did. Thanks to <a href="http://www.flyingpenguin.com/?p=5878">this post</a>.<br />
<br />
Follow it. It works.<br />
<br />
Here are the keypoints and some added tips from the comments.<br />
<ul><li>Add yourself to both the vboxusers and audio groups.</li>
<li>Change the USB filter settings so that only Name and Vendor ID have values. DELETE EVERYTHING ELSE. It's not recommended. It's mandatory!<br />
</ul><br />
After all this, I was able to restore my iPhone without problems. Booyah!Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-27620901087335786172011-08-29T10:00:00.000-07:002012-07-15T22:12:10.795-07:00Rails 3.0: RSpec 2 + Machinist + ActiveRecordRSpec 2 usually cleans up after itself if you set config.use_transactional_fixtures to true. However, if you use Machinist 2, this isn't the case. Apparently Machinist likes to keep around a cached version to speed things up. This is bad when trying to run independent tests.<br />
<br />
To prevent this from happening, add this to config/environments/test.rb.<br />
<pre class="prettyprint lang-rb">Machinist.configure do |config|
config.cache_objects = false
end
</pre><br />
<h2>References</h2><a href="http://blog.angelbob.com/posts/315-RSpec-not-clearing-database-when-you-use-machinist---published-rails">http://blog.angelbob.com/posts/315-RSpec-not-clearing-database-when-you-use-machinist---published-rails</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-89105812945662568072011-08-28T10:00:00.000-07:002012-07-15T22:14:15.464-07:00Rails 3.0: PostgreSQLIf you're starting fresh, getting a Rails application running on PostgreSQL can be rather involved.<br />
<br />
Install PostgreSQL on Ubuntu.<br />
<pre class="prettyprint lang-bsh">sudo apt-get install postgresql libpq-dev pgadmin3 -y
</pre><br />
Create a new Rails application with PostgreSQL.<br />
<pre class="prettyprint lang-bsh">rails new <project name> -d postgresql
</pre><br />
If this is an old project, install the gem in Gemfile.<br />
<pre class="prettyprint lang-rb">gem 'pg'
</pre><br />
Create the PostgreSQL user. The username will be the same name as your project which can be found in config/database.yml.<br />
<pre class="prettyprint lang-bsh">sudo su postgres -c psql
# Enters the psql console.
create user "<username>" with [superuser] password "<password>";
# Outputs CREATE ROLE.
\q
</pre>The superuser keyword is optional but makes things easier in development.<br />
<br />
If you get the error "FATAL: ident authentication failed", edit /etc/postgresql/8.4/main/pg_hba.conf.<br />
<pre class="prettyprint lang-bsh">local all all ident
</pre>to<br />
<pre class="prettyprint lang-bsh">local all all md5
</pre><br />
Restart PostgreSQL.<br />
<pre class="prettyprint lang-bsh">sudo service postgresql restart
</pre><br />
Create the development and test databases through the terminal.<br />
<pre class="prettyprint lang-bsh">createdb <project name>_development -U <username> -W
createdb <project name>_test -U <username> -W
</pre><br />
<h2>References</h2><a href="http://olmonrails.wordpress.com/2008/08/12/switching-rails-to-postgresql/">http://olmonrails.wordpress.com/2008/08/12/switching-rails-to-postgresql/</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-70175449843370440952011-07-21T10:00:00.000-07:002011-07-21T10:00:02.055-07:00Ubuntu 11.04: Window Docking ShortcutsI stumbled upon some new shortcuts in Natty Narwhal to dock a window in a certain position.<br />
<br />
Try out Ctrl+Alt+<Number Pad Key>. This will dock your window according the position of the number in the number pad. Note that it doesn't work with the numbers along the top of the keyboard.<br />
<br />
1: Bottom left corner<br />
2: Bottom<br />
3: Bottom right corner<br />
4: Left<br />
5: Middle (but not maximized)<br />
6: Right<br />
7: Top left corner<br />
8: Top<br />
9: Top right corner<br />
0: Maximize<br />
<br />
If you press the same number several times, it will change the size of the window.<br />
<br />
I found this super handy when I needed to fit things inside my monitor, such as having 2 terminals side-by-side.<br />
<br />
Try it out and let me know what you think down below in the comments!Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-46387866251839029362011-07-13T10:00:00.000-07:002012-07-15T22:15:35.903-07:00Ubuntu 11.04: Redshift<a href="http://jonls.dk/redshift/">Redshift</a> is a program that changes the temperature of your monitor according to the time of day. It basically emulates sunset and encourages your body to sleep earlier. Something that I desperately need to do.<br />
<br />
I recently upgraded to Ubuntu 11.04 Natty Narwhal, and was happy to find that Redshift had made it into the repositories! Unfortunately, after installing both the application and its GUI counterpart, it did not start.<br />
<br />
I tried it in the terminal and to my dismay, I got the following:<br />
<pre class="prettyprint lang-bsh">> redshift
No clock applet was found.
Initialization of gnome-clock failed.
Trying next provider...
Latitude and longitude must be set.
</pre><br />
So what's going on? Well, as of Ubuntu 11.04, Gnome is no longer the default. It's Unity. Hence, there is no gnome-clock. <br />
<br />
Luckily, Ubuntu uses Redshift v1.6. In this version, a configuration file can be added! Just create the file ~/.config/redshift.conf with the following:<br />
<pre class="prettyprint lang-bsh">[redshift]
location-provider=manual
[manual]
lat=49.3
lon=123.06
</pre><br />
After saving the file, you can now restart Redshift from the GUI.<br />
<br />
Enjoy and sleep early!Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-58130775900678790092011-06-09T11:01:00.000-07:002012-07-15T22:17:54.859-07:00Logging Bootup/Startup ScriptsI was writing some startup scripts in /etc/init.d/ to be run during bootup. However, there was a problem and the scripts weren't running properly. Unfortunately, there were no logs anywhere.<br />
<br />
<h2>System Wide Logging</h2>I found a solution in Ubuntu which was to open up /etc/default/bootlogd and set the option to yes. You supposedly see the boot logs in /var/log/boot. However, I found it was writing to /var/log/boot.log. Sort of. I got partial output (about 6 lines). The file was never fully written to.<br />
<br />
<h2>Script Specific Logging</h2>I found a workaround. Instead of using a system wide log, use a script specific log. Add this to your script. It will log all output.<br />
<pre class="prettyprint lang-bsh">exec > /tmp/debug-my-script.txt 2>&1
</pre><br />
<h2>References</h2><ul><li><a href="http://ubuntuforums.org/showthread.php?t=49925">Ubuntu boot log</a></li>
<li><a href="http://serverfault.com/questions/126696/ubuntu-9-10-how-do-i-troubleshoot-a-startup-script-that-doesnt-appear-to-run">Logging to file</a></li>
</ul>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-73331432249444413622011-06-07T10:17:00.000-07:002011-06-07T10:17:20.512-07:00Automatic Server Bootup on Power FailureImagine a power failure where your servers are running. Of course, they should be plugged into a UPS, but what if that goes down too? Your server will power off.<br />
<br />
When the power comes back, your server will remain quiet unless you tell your servers to come back to life by themselves.<br />
<br />
There are 2 things you must do in the BIOS to make this happen.<br />
<br />
<ol><li>Tell the server to bootup after a power failure. This is the AC Power Loss Restart option in the BIOS. This should be set to On.</li>
<li>Ignore a missing keyboard. There is an area in the BIOS that handles halting on errors. It should be set so that it ignores keyboard errors. If this is not ignored, the server will wait for the user to press F1.</li>
</ol>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-76665189719651974312011-03-05T17:08:00.000-08:002012-07-15T22:19:25.004-07:00Rails 3.0: Installing HamlInstalling Haml is easy. Open up Gemfile.<br />
<pre class="prettyprint lang-rb">gem 'haml'
</pre><br />
Install.<br />
<pre class="prettyprint lang-bsh">bundle install
</pre><br />
Now start naming your HTML files with a .haml extension, such as index.html.haml.<br />
<br />
<h2>Cheat Sheet</h2>Here's a quick cheat sheet to get you started.<br />
<pre class="prettyprint lang-rb">#id
.class
%tag
%a{ :href => 'http://wesleymwwong.blogspot.com' }
/ HTML comment
= output
&= escaped output
!= not escaped output
- ruby
-# ruby comment
#{ inline ruby }
:javascript
!!! strict
!!! 5
</pre><br />
<h2>References</h2><ul><li><a href="http://haml-lang.com/docs.html">Haml</a></li>
</ul>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-47569690668774005302011-02-27T10:00:00.000-08:002012-07-15T22:20:15.505-07:00Why Haml?When things are modular, simplicity and understanding have a chance to precipitate. Working with something that deals with a multitude of responsibilities is mentally tiring.<br />
<br />
When using markup like HTML, there is a distinction between structure and layout. HTML provides the structure and CSS provides the layout. You should be able to separate out the two. The HTML should still make sense and be organized even without the CSS. This idea is very well demonstrated with <a href="http://csszengarden.com">CSS Zen Garden</a>.<br />
<br />
<h2>Inline CSS, I Banish Thee!</h2>So where does Haml come into all of this? With Haml, I find it very hard to use inline CSS. Some may think this is a disadvantage because you can't do quick tweaks (read hacks). Hacks are usually done in the moment with the thought of fixing it up afterwards. Unfortunately, these usually end up sticking around permanently since it works and there is always something more important to do. You end up with HTML that does more than structure. With Haml, you are more inclined to let CSS handle the layout.<br />
<br />
<h2>My Poor Fingers</h2>Haml saves you a lot of keystrokes. It is much less verbose than HTML and ends up saving you a lot of time. With less characters required, it is easier to see the structure of the entire page at a glance, which helps once you move onto styling the page with CSS.<br />
<br />
<h2>This Looks Familiar</h2>Once you start converting your HTML to Haml, you'll notice something. It kind of looks like CSS! Because of this, it makes the CSS easier to write and understand.<br />
<br />
<h2>Haml</h2>If you have time, check out <a href="http://haml-lang.com">Haml</a> and let me know what you think.Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-84367531335035144402011-02-10T10:00:00.000-08:002012-07-15T22:20:50.442-07:00Rails 3.0: Cucumber + MockingI know. Cucumber is used for integration tests. Integration tests and mocking shouldn't even be in the same sentence. However, there are times when practicality trumps theory.<br />
<br />
For instance, emails. How do you ensure that emails have been sent/received? <br />
<br />
Another example is MailChimp. When a user signs up, you add them to a MailChimp list. Now, whenever you need to create a user, your app hits MailChimp. Since you are suppose to start with a clean slate, you now need to clean out the MailChimp list. This gets tedious and time consuming.<br />
<br />
To speed things up, you may want to mock certain tasks like these.<br />
<br />
Cucumber supports RSpec mocking (aka doubles) pretty easily.<br />
<br />
Open up features/support/local_env.rb (or your custom config file for Cucumber)<br />
<pre class="prettyprint lang-rb">require 'cucumber/rspec/doubles'
</pre><br />
Done! Enjoy!<br />
<br />
(Just as a note, I would test MailChimp without mocking when testing signup. I would mock it out in all other cases. Unfortunately, I haven't figured out how to test emails for real. If you have any suggestions, please leave a comment. I would love to hear it!)Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0tag:blogger.com,1999:blog-3431504344328802897.post-73348274769398747362011-02-04T10:00:00.000-08:002012-07-15T22:22:30.413-07:00Rails 3.0: Devise + Mongoid + RSpecDevise removes the mundane job of writing all the code required to handle a user account. Plus, it supports Mongoid.<br />
<br />
The following is a non-exhaustive list of tasks Devise takes care of for you:<br />
<ul><li>signup</li>
<li>forgot/reset password (including emails)</li>
<li>confirmation emails</li>
<li>password encryption</li>
<li>login</li>
<li>logout</li>
<li>editing account info</li>
<li>locking accounts</li>
<li>session expiration</li>
</ul><br />
All this is available out of the box. Along with the goodies that are pre-packaged, Devise is fully customizable.<br />
<br />
<h2>Installation</h2>Open Gemfile<br />
<pre class="prettyprint lang-rb">gem 'devise'
</pre><br />
Install<br />
<pre class="prettyprint lang-rb">bundle install
rails generate devise:install
</pre><br />
You will need to setup your mailer if it isn't already setup. Devise depends on the default host being set, so ensure the following is set<br />
<pre class="prettyprint lang-rb"># ... other mailer settings
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
</pre><br />
Don't worry! Devise is smart and has already detected that you are using Mongoid at this point and not ActiveRecord. It has also created config/initializers/devise.rb. This is where you can configure Devise. Take some time to familiarize yourself with all the options and uncomment any that you would like to use. I'll wait.<br />
<br />
<h2>Test Helpers</h2>If you are using RSpec, create spec/support/devise.rb with<br />
<pre class="prettyprint lang-rb">RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
</pre><br />
Now you have access to things like<br />
<pre class="prettyprint lang-rb">sign_in @user
sign_out @user
</pre><br />
<h2>Create a User model</h2>It is time to create a User!<br />
<pre class="prettyprint lang-bsh">rails generate devise user
</pre><br />
This generates a user model at app/models/user.rb with some Devise specific lines of code. Include the modules that you want and remove the ones you don't.<br />
<br />
Believe it or not, Devise is now properly hooked up and ready!<br />
<br />
<h2>Routes</h2>Devise automagically generates all the user routes required for handling the user account. If you look in config/routes.rb, you'll notice<br />
<pre class="prettyprint lang-rb">devise_for :users
</pre><br />
To see all the routes<br />
<pre class="prettyprint lang-bsh">rake routes
</pre><br />
You will notice a bunch of user routes. Fire up your server and navigate to localhost:3000/users/sign_up. Voila!<br />
<br />
As a quick reference, here are some useful routes:<br />
<ul><li>signup: new_user_registration_url</li>
<li>edit account: edit_user_registration_url</li>
<li>login: new_user_session_url</li>
<li>logout: destroy_new_user_session_url</li>
</ul><br />
<h2>References</h2>I encourage you to take a look at the Devise home page as there is a wealth of information there.<br />
<br />
<a href="https://github.com/plataformatec/devise">https://github.com/plataformatec/devise</a>Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com1tag:blogger.com,1999:blog-3431504344328802897.post-13702905836958267252011-01-12T10:00:00.000-08:002012-07-15T22:24:12.760-07:00Ubuntu: Installing FontsIt's very easy to install fonts in Ubuntu. Fonts usually come in a zip file. There may be several different versions of the same font with different extensions. I've currently tried this with ttf and otf fonts.<br />
<br />
System-wide fonts are located at /usr/share/fonts. However, I prefer to keep things to myself, so I will install it in my home directory.<br />
<br />
Create a .fonts directory in your home if it doesn't exist already.<br />
<pre class="prettyprint lang-bsh">mkdir ~/.fonts
</pre><br />
Extract your font to the .fonts directory. You only need to extract one of the font versions. For example, if the zip file contains both myfont.ttf and myfont.otf, you only need to pick one of them, like myfont.ttf.<br />
<br />
Refresh the font cache.<br />
<pre class="prettyprint lang-bsh">sudo fc-cache -f -v
</pre><br />
If you had an application open, now would be a great time to restart it. You should now see the new font.Anonymoushttp://www.blogger.com/profile/17537700868977533645noreply@blogger.com0