Perpetually In Beta.

Archive for August, 2008

Standford University - Programming Paradigms - Lecture 3

without comments

The following is a brief overview of Lecture 3 of the 'Programming Paradigms," a programming class taught at Standford University.  Screenshots and Code are included from the lecture.  The 'Programming Paradigms' lectures can be found in iTunes.  The link is on the Open Standford Website.  The following lecture covers Casting Types, Structs, Arrays, Arrays in Structs, and the beginning of programming generics in C.

Casting Types in C++

The first two examples deal with casting in C.

double d = 3.1416
char ch = * (char *) &d;
cout << ch << endl;

A double of 3.14 or pi is declared then cast as a character ch. &d is a pointer to the first byte address in d.  (char *) says, "Oh, it's not a double it's a character."  The final * "de-references" that value which means it copies the value to ch not the address.

short s = 45;
double d = *(double *) &s

A two byte figure that has 4 and 5 in it.  &s points to the first byte address of s.  (double *) is a brute force interpretation of &s.  The code is essentially saying, "Oh, that never pointed to a short.  It always pointed to an eight byte double."  The first two bytes of the double "d" will be 4 and 5 and the rest will be blank.

A student asks a question about Endian(ness). When a "1″ is represented as two byte short in Big Endian, the right most bit in the right most byte is a one.  Most Linux Machines store bytes in the reverse order or "Little Endian."  When a "1″ is represented as a two byte short in Little Endian, the right most bit is set in the left most byte.

Structs in C++

struct fraction {
int num;
int denum;
};
 
fraction pi;
pi.num = 22//sets num to 22
pi.denum = 7// sets denum to 7

When a stuct is declared with two four byte ints, they are stacked like dominos in memory.  The num variable is on the bottom.  The denum is stacked on top of the num. Setting the two fields is easy enough.  One sets the num and denum fields with the (.) dot operator.

Now things become a little crazier.

((fraction *) &(pi.denum))->num = 12;

Let's break it down.

&(pi.denum)

points to the top address of the struct — the denum address.

(fraction *) &(pi.denum)

Casts the top address as a struct with two int variables.  Pi.denum becomes the bottom address (or num address).

((fraction *) &(pi.denum))->num = 12;

Sets the previous pi.denum, which is now pi.num, to "12."
Tricky Tricky.

((fraction *) &(pi.denum))->denum = 33.

Sets the space above the original pi.denum to 33 even though the address isn't owned by the struct.  There is no legal way to get to this and print it out, however, the memory is set anyway.

Arrays in C++

int array[10];

This call allocates 40 bytes of memory.  4 bytes for each of the 10 blocks in the array.

array[0] = 44;

Puts 44 in the first four bytes of memory, or the zero place in the array.

array[9] = 100;

Puts 100 in the last four bytes of memory, or the 9th place of the array.

Therom:  array ≡ &array[0]
The array is completely synonymous with a pointer to the first address of the zero(th) entry.  When one passes an array to a function, you aren't passing the array itself (and all the memory).  You are passing the address to the zero(th) entry and from there you can jump to whatever place you want in the array.

array[10] = 1;

If for some reason you mess up and try to assign the number one to the 11th entry in the array.  The computer will try to place a one in that location even though that memory isn't preallocated.

array[-4] = 77;

C++ even tolerates brute force.  You can assign a number to a negative offset in memory.  There is no boundary checking in C and C++.

Theorem:  array + k ≡ &array[k]

This is pointer arithmetic.  K is automatically scaled based on the type system.  In the case above, k is an int, therefore k is scaled in 4 byte increments.

Theorem:           *array ≡ array[0]

(array + k) ≡ array[k]

When array is de-referenced, the above is equal to the value stored in the array — not the address.

int arr[5];
arr[3] = 128;
((short *) arr[6] = 2;
cout<< arr[3] << endl;
640

Each int is compsed of four bytes.  Each short is composed of two bytes.  The second and third statement above actually set the same bytes in memory.  arr[3] sets the memory 12 bytes over (3 * 4 (size of int) = 12).  ((short *)arr[6]) (6 * 2 (size of short) = 12) also sets the memory six bytes over.  Although, 128 fits in the 15th and 16th byte, while 2 is placed in the 13th byte.  When arr[3] is printed to the screen, the value printed out is 128 + 512 = 640 ( 2^9 + 2^7 = 640).

Arrays in Structs

struct student {
char * name;
char suid[8];
int numUnits;
};
 
student pupils[4];
pupils[0].numUnits = 21;

Sets numUnits in the first instance of pupil to 21

pupils[2].name = strdup("Adam");

Creates memory on the heap with "Adam�"  name points to this memory on the heap.

pupils[3].name       = pupils[0].suid + 6;

The name character pointer in the fourth instance of pupil points at the address starting at the sixth character in the first instance of the struct pupil

strcpy(pupils[1].suid, "40415xx");

Copies "40415xx" to the suid character array starting at the first character in the second instance of pupil.

stcpy(pupils[3].name, "123456");

Since pupil[3].name points at the address starting at the sixth character in the first instance of the struct pupil, starting from that location "123456″ is copied.  This writes over the 21 which was previously assigned to pupils[0].numUnits.

pupils[7].suid[11] = 'A';

Even though an eighth pupil isn't properly allocated, the computer still tries to write 'A' to the 11th character into the suid character array.  Will it succeed?  Maybe.

How to Write Generics In C

int x = 7;
int y = 117;
swap(&x, &y)
 
void swap(int *ap, int *bp)
{
 
int temp = *ap;
*ap = *bp;
*bp = temp;
 
}

Two addresses are passed to the swap function.  Ap and bp point to x and y respectively.  The first line in the swap funtion copies 7 (the value of what ap points to (x)) to temp — so temp is set to 7.  The second line, copies the 117 (the value of what bp points to (y)) to whatever ap points to (x) - so seven is replaced by 117.  Temp, whose value is seven, is then copied to y or what bp points to.

Written by codingwithoutcomments

August 31st, 2008 at 4:30 pm

Til Death Due Us Part - Project Euler - Problem 3

without comments

Project Euler "is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems."

Lot's of programmers recently have been using Project Euler as a form of 'Code Kata:'  a philosophy that believes that greatness comes through diligent practicing.  Steve Yegge written on the subject as well as Kathy Sierra.  The idea is that you can be insanely great at anything if you practice at it.  Sure, some people are natural geniuses — and you will never be better then them.  But if you want to, you can be in the top 1% of learned people on any particular subject.

I'm not sure if I believe them, but heck, i think that the idea inspires lots of mediocre programmers ( like myself ) to wake up each day and learn new stuff.  And that in itself is worth something, right?  I do believe that if you just set aside one hour per day to learn something new, you can become quite proficient in anything at all in a shorter period of time then you even imagined.  Most people have a hard time with this though.  They have a seeing that just one hour per day can lead to incredible results.  I myself was in this category until I learned the 'Til Death Due Us Part' productivity method.  On my Google homepage, I have the following widget on display:

The 'Countdown' widget shows me the (estimated) number of days I have until I die.  Instead of brimming over with horrible sadness everyday, the huge number of days I have left actually motivates me.  I just think about this simple fomula:

Number of Hours Per Day * Number of Days Til Death = Total Number of Hours

If I started today learning Ruby and practiced Ruby one hour per day, by the end of my life I will have practiced Ruby 17,193 hours.  What are you NOT going to be good at after practicing for that long?  With that in mind, you have no excuses.  It is never too late for you to learn anything… well, provided you are not already 83 years old.  Then I'd stick to shuffle board.

I've been teaching myself Ruby the last couple months and just recently started going through the problems on Project Euler.  Problem 3 posed the following question:

The prime factors of 13195 are 5,7,13, and 29
What is the largest prime factor of the number 600851475143?

From wikipedia, "In number theory, the prime factors of a positive integer are the prime numbers that divide into that integer exactly, without leaving a remainder."

My solution to the problem in Ruby is below:

The first dilemma I faced while solving the problem was generating a list of prime numbers.  I'm going to be honest, I didn't generate squat.  I kind of cheated.  I found a list of 10,000 prime number online.  When the class PrimeFactorFinder is initialized, the list of numbers is opened, the prime numbers are "scanned" in using Regular Expressions and added to the array @PrimeNumbers.  There is an way to actually generate prime numbers in Ruby I discovered.  One can use the mathn standard ruby library as seen below:

require 'mathn'
primes = Prime.new
factor = primes.next

The next hurdle was finding the list of prime factors.  This was found by modulo(ing) the numberToFactor by each prime number. If the former expression yields '0′ then the prime number divides into the numberToFactor exactly and is a 'Prime Factor.'

All in all a pretty simple exercise, yet it required me to use Ruby's Arrays, File IO, and Regular Expressions. Code Kata indeed.

Written by codingwithoutcomments

August 28th, 2008 at 1:20 pm

Creating a IRC (Internet-Relay-Chat) Client in Ruby - First Steps

with one comment

Homer was the beginning of my IRC obsession.  Homer was an IRC client for the Macintosh operating system in the 1990's.  I still kind of remember what it looked like.  It had a black background with white text.  Everytime you typed something, a little animated Homer (Simpson) would dance around in the left hand corner of the screen.  For years I would come home from school, hit the computer, and spend hours talking to people all over the world.  IRC is and was the original chat (ok besides BBSess).  It was fascinating.

The other day I was contemplating what kind of project I could work on that incorporates Ruby as the back-end and Shoooes as the front-end and IRC came to mind as a viable project idea.  I asked the nice people at Stackoverflow how one might get started on this particular project idea (besides knowing Ruby and shoes), and they were nice enough to link me to some important documents.  The wikipedia entry provided a good overall overview while the nitty gritty IRC specification details can be found in RFC 1459.

Pre-Existing Ruby Client

I did a quick search on google for 'IRC' and 'Ruby' and came across Lurker's Blog.  Lurker coded a very basic command line IRC Client which already provides the following functionality:

What can it do?
1) join and talk to multiple channels, as well as handle private chats (what is just enough for most of the people out there)
2) change user mode
3) send any IRC command entered by user (but you do have to know what you are doing and you do it at your own risk)
4) receive dcc file sends (resume supported)
5) process dcc download queue
6) record channel conversations to file

Lurker's code (which can be found here), to me, seems like a perfect jumping-off point for understanding exactly how IRC works while providing the basic IRC functionality for my project.   I messaged Lurker and asked if I could use some of his code in my project and he gave me his blessing.  Over the next few weeks I intend to take the following steps towards my graphical Ruby IRC client.

  1. I'll first take time to understand Lurker's Pre-Existing Code.  I'll go through the code, comment it, then talk about it's overall structure and methodology on this blog.
  2. Lay down Lurker's Pre-Existing code in the Model-View-Controller Framework.  MVC is a powerful design pattern that helps isolate the guts of the code (The Controller) with the Graphical Front-End (The View).  On this blog, I'll talk about how to implement MVC in Ruby.
  3. Design the GUI in Shoes.  Make some pretty drawings.  Post them online.
  4. Code the GUI in Shoes based on the pre-existing basic IRC functionality.
  5. Continue to add additional features to Luker's basic IRC code as the need arises.

Written by codingwithoutcomments

August 27th, 2008 at 5:54 pm

Posted in Programming

Tagged with , , , , , , , ,

The Not-So-Boring Guide to Subversion (Episode 2)

without comments

Chris says, "You are ever-so-slightly urged to read Episode-One of the Not-So-Boring Guide to SVN before you read Episode-Two. And no, I would not, could not, on a train."

Chris says, You are ever-so-slightly urged to read Episode One of the Not-So-Boring Guide to SVN before you read Episode Two. And no, I would not, could not, on a train.

Welcome back to the Not-So-Boring guide to SVN.  On the last episode, we learned about Checking Out files from the dark-scary Repository, making a commit-ment to the files if we make changes to them, and making sure we Update our files on occasion to verify that we are working with the latest-greatest code.

Creating your own Repository

All of the above options assume that you're working for an Open-Source project or a company where the SVN Repository is already set up and ready-to-go.  You, however, I know are different.  You've got your own ideas. You don't want to work for the man.  You want to be the man.   You've been watching the Apprentice, listening to Venture Voice, and are done and gets things smart.  Great.  Have I got the answer for you!

The create function creates a repository where-ever you want it.  You want it on the moon?  No Problem.

$ svn create /repos/on/the/moon

What about on an elephant?

$ svn create /repos/on/the/elephant

If you don't want to host it locally, you can always check out the plethora of hosting options.  Services like Beanstalk and Dreamhost making hosting a Subversion Repository easy cheesy.

Next, import your project into the Repository so it can be checked out and worked on by you and your army of programming minions that you will hire for paltry wages but that you will supply with unlimited free cokes, 30-inch monitors, and Aeron Chair's.

$ svn import ProjectFileTree file://repos/on/the/elephant/ProjectName

Once in the repository, you can use the check-out command to begin work on the project.

$ svn checkout file://repos/on/the/elephant/ProjectName

And while we're add it, go ahead and update those files.  You never know where they've been.

$ svn update

All Deer May Cough (On) Moles

Now you're ready to go ahead and edit those files to your little heart's content.  Subversion automatically detects which files have been changed (remember the secret .SVN files).  BUT (and this is a BIG BUT), if you intend to make any changes to the Project File Tree such as adding a new file, deleting a file, copying a file, moving a file to another location, or making a new directory, SVN needs a little guidance.  Thus, the following commands are provided.

Add a File or Directory to the Repository.

$ svn add VeryPracticalFileName

Delete a File or Directory from the Repository.

$ svn delete ExtreamlyPracticalDirectoryName

Copy a File and Add to the Repository

$ svn copy Roger CopyOfRoger

MkDir creates a new Directory in the Repository.

$ svn mkdir DirectoryName

Move is kind of wierd.  Strange even.  It moves a file from one part of the Repository to the other.

$ svn move Here There

is the exact same thing as as saying:

$ svn copy Here There
$ svn delete Here

Strange huh?  But it makes sense if you think long and hard about it.  Because if you were moving 'Here' to 'There,' it wouldn't be 'Here' anymore would it?  It would be 'There.'  Actually, think of the move command like the Cut command on your computer.  If you cut a file from a directory and paste it in another directory, you have essentailly moved it to the new directory.  Whew.

Break Time:  Here's a picture of My Dear Aunt Sally.  Stunning isn't she?

My Dear Aunt Sally

If you remember back to your years of golden locks and curls, Please Excuse My Dear Aunt Sally was a way to remember the Order of Operations: Parentheses, Exponents, Multiplication, Division, Addition, Subtraction.   To help you remember Add, Delete, Mkdir, Copy, and Move (the four things you may have to do if you intend to make any changes to the projects file tree), come up with your own Memory Jogging Device and write them in the blanks below!

ADD               DELETE           MKDIR              COPY             MOVE

____________     ____________   ____________   ____________   ____________

No, I don't care about the frequency.  What's the status Kenneth?

Before making a commitment to the Repository, it is in good form and fashion to run a status on your Working Copy.  Status gives you an overview of the changes you've made to your Working Copy since your last commit.

$ svn status
A    who/is/this/me.cpp
M   doing/this/synthetic.h

A is for Apple.  In Subversion speak,  'A' means that your file me.cpp is scheduled for addition.
M is for Moose. In Subversion speak, 'M' means that your file synthetic.h has been modified since your last commit.
C is for Cardigan.  In Subversion speak, 'C' means that your file is in a state of conflict!
D is for Done.  In Subversion speak, 'D' means that your file is scheduled for deletion.

There are several reasons why the status command should become your new best friend.

  1. All the other kids are doing it and it's better then jumping off a cliff.
  2. By seeing the changes you have made, you will have a better idea of how to document those changes in your -m flag once you decide to commit those changes.
  3. The status can alert you to potential conflicts between the changes you have made and the local changes in your working copy.
  4. You don't have to have a network connection.
  5. See Number One.  (Oh no, infinite loop!)

I'm not going to spend my life being Burnt Sienna either.

I used to love Michael Jackson.  I listened to 'Dangerous' like a million times growing up.  One of my favorite Michael Jackson videos was "Black or White."  You know the where Macaulay Culkin is punk teenager and at the end all these people from different backgrounds and ethnicities morph into each other.  Like a man from African becomes an Indian woman.  And that woman becomes a Chinese Man, who then turns into a New Yorker from the bronx. This is the same video in which Michael sings, "I'm not gonna spend my life being a color" which I think it a great thing to say because we I too think that we should not spend our lives being "green" or "acqa" or "mother-of-pearl," but instead be human beings.  Anyway, the entire premise of the video was great because it preached that we should look past our differences and embrace our collective similarities.

Thankfully, Subversion doesn't see it this way.  It does not look past our differences.  In fact, it keeps record of them.   Using the Diff command, one can see the differences between your working copy and the last version that has been committed.

$ svn diff
Index: ThreatenAnimal.rb
===================================================================
--- ThreatenAnimal.rb    (revision 5)
+++ ThreatenAnimal.rb    (working copy)
@@ -1,2 +1,2 @@
-puts 'Stop Looking At Me Pignot Noir!'
+puts 'Stop Looking At Me Pignot Grigio!'

It seems as if i changed 'Stop Looking at me Pignot Noir' to 'Stop looking at me 'Pignot Grigio.'  The Diff command prints the differences to the console window in a very easy-to-understand format.  Are you ready?

  • Lines that have '-' at the beginning are removed.
  • Lines that have '+' at the beginning are added

Instead of printing all this useful information to the console where it could possibly be lost forever, why not print it to a file?

$ svn diff > thedifferencefile

Now you can E-mail the file to your friends, IM it to your significant other, facebook it just "because you can", or print it for religious reasons.

We all Make Mistakes

When I was six grade I got caught shop-lifting a yin-yang chain from the spectacular Spencer's gifts.  I put it in my hat.  The store-man saw me in the security mirror.  He took me to the back and called my parents.  My dad came and yelled at me.  He took me home.  My mom yelled at me.  I was ashamed.  What I am saying is that we all make mistakes, but unfortunately, unlike Subversion, real-life doesn't have a revert command.

Above, in ThreatenAnimal.rb I changed the line 'Stop looking at me Pignot-Noir' to 'Stop looking at me Pignot-Grigio' which, in hindsight, was kind of dumb.  I mean, I really don't want Pignor-Noir to look at me, but the bottom line is that Pignot-Grigio,  with it's fantastic flavorings of citrus and rutabaga, can look at me all day long if it wants to.  I made a mistake.  How can I possibly go back to how things used to be?

$ svn revert ThreatenAnimal.rb
Reverted 'ThreatenAnimal.rb'

Simple.  The Revert command reverts the file to it pre-modified state by overwriting it with the cached version of the file in the secret-hidden .svn folder.  NOTE:  This can only be done if the file has not-yet been committed.

Conflict Resolution 101

The situation is as follows:  You are driving down the left-lane of a two-lane highway when traffic comes to a stand-still.  You see that this is because your lane is coming to an end up ahead because of construction and everyone in your lane is merging into the right lane.  You think of yourself as a nice-guy good-citizen type, so instead of waiting till the very last second to merge, you put your right-blinker on, and merge your way into the right lane whenever you can get someone to let you in.  I found out this week that this is stupid way to merge.  In fact, you think you are doing the correct thing, the morally-upright thing, but really you are slowing down traffic even more.  If no one were to merge until the very last second, you would save upwards of 20% or more time.  But there's nothing to tell people this.  No sign or indication.  In fact, it is counter-intuitive to wait until the very last second to merge and if you wait till the very last second everyone else thinks you are a jerk.

Merging files in Subversion in tricky.  It's not easy, and, like on the highway, you could come off looking like a big jerk.  Let me demonstrate.  You edit ThreatenAnimal.rb one more time changing "Pignont Noir" to "Madame Bovary."  At the same-time, your teammate Jake Gyllenhaal checks-out, edits, and commits ThreatenAnimal.rb to look like the following:

puts 'Stop Looking At Me Pignot Noir!'
puts 'But, I mean, you can look look look'
puts 'If you really really want to'

Jake obviously has some feelings for Pignot Noir.  Which I think is a little strange.  But you don't know about these changes yet.  So before you commit your changes, you decide to do a final update to make sure everything is in tip-top order.

$ svn update
C    ThreatenAnimal.rb
Updated to revision 7.

The 'C' next to TheatenAnimal.rb stands for Conflict!

When a Subversion Conflict happens three new files are created in the same directory as TheatenAnimal.rb.

$ ls
ThreatenAnimal.rb    ThreatenAnimal.rb.r6
ThreatenAnimal.rb.mine    ThreatenAnimal.rb.r7
  • ThreatenAnimal.rb now contains special markers like <<<<<<<< and ====== and >>>>>>>> which "visibly demonstrate" the differences between between your copy and Jake's to help you make a decision about how to merge both files.
  • TheatenAnimal.rb.mine contains the your file as it existed in your Working Copy before you did the update.  Ex.  puts 'Stop Looking at me Madame Bovary!'
  • ThreatenAnimal.rb.r6 contains the file as it looked when you originally checked it out from the Repository.  Ex. puts 'Stop Looking at me Pignot Noir'
  • TheatenAnimal.rb.r7 contains Jake's version of the file that he committed to the Repository

At this stage you've got choices.

  1. Merge the conflict by hand.  Open up TheatenAnimal.rb, look at the markers.  Make decisions.
  2. Copy one of the temporary files on top of your working file.
  3. Run svn revert TheatenAnimal.rb to throw away all of your changes
  4. Freak out.

While #4 seems incredibly promising, option #1 is possibly more satisfying.  But who I am to judge?  So you open up TheatenAnimal.rb in your favorite text editor and see the following:

<<<<<<<<< .mine
puts 'Stop Looking At Me Madame Bovary!'
=======
puts 'Stop Looking At Me Pignot Noir!'
puts 'But, I mean, you can look look look'
puts 'If you really really want to'
>>>>>>>>>> .r7

The text between <<<<<<<<.mine and ===== shows your copy
The text between =======  and >>>>>>>>> .r7 shows Jake's copy

Now, this is where you have to be careful.  A "big jerk" would just delete all the changes Jake made (which would be sad because he's a very busy man between programming and his full fledged acting career) and keep all of your own changes.  But you aren't a jerk, are you?  So you call up Jake, and the following conversation takes place.

Jake: "Hello?"
You:  "Jake!"
Jake:  "Oh hey man."
You:  "Hey, uh yeah.  Just a quick question.  I know you are busy making Donnie Darko II."
Jake:  "Yeah, it's cool man.  What's up?"
You:  "Well, you know TheatenAnimal.rb?  I know you are in love with Pignot Noir, but I really need it to be Madame Bovary.  She's, well, theatening, but classic.  You know?  Is that cool?"
Jake:  "Oh yeah man.  I totally understand.  I'm in love with Madame Bovary too, but don't really want her to loook at me.  It's complicated."
You:  "So, you trust the changes I'll make?"
Jake:  "Do it Doug."

So, you merge both Jake's file and your file together.  The final outcome is below.

puts 'Stop Looking At Me Madame Bovary!'
puts 'But, I mean, you can look look look'
puts 'If you really really want to'

The conflict between You and Jake is now resolved.  Tell subversion that.

$ svn resolved ThreatenAnimal.rb
Resolved conflicted state of 'ThreatenAnimal.rb'

The resolve command resolves the conflict and deletes all the temporary files created when the whole conflict between you and Jake started.

You are now ready to commit the merged file.

$svn commit -m "My compromise with Jake with a strange fear and a love of Madame Bovary"
Sending        ThreatenAnimal.rb
Transmitting file data .
 
Committed revision 8.

Version Control can be complicated sometimes especially when celebrities are involved.  Jake's cool, but most of them are a bunch of babies.

Written by codingwithoutcomments

August 23rd, 2008 at 2:39 pm

Blogging Shoooooes. The Simple-Accordian Application.

without comments

shoooes!

shoooes!

Shooooes is a cross-platform magical GUI library for Ruby created by the notorious whytheluckystiff author of Why's Poinant Guide to Ruby and Try Ruby! (in your browser). Yes, he is busy to the infinite power.  I am a big fan of all his work.

Included with the Shooooes software, is a frighteningly large pack of sample applications.  These sample applications are fun, swift, and swiun (a combination fo both swift and fun).  What they aren't, however, is well commented.  (They are, in fact, zero commented.)  I do understand _why's reasoning though.  Cluttering code up with comments makes it harder to read, but easier to understand.  I'd advise, trying to figure out the program with the un-commented version first, but if you hit a snag, know that the commented version is there for a little guidance.

Simple-Accordion

Today's Application is the Simple Accordion.  If you don't have the code you can download it here, or if you want to download the commented version of the Simple-Accordion then click here.

Simple-Accordion.rb

Simple-Accordion.rb

The Simple-Accordion is a relatively simple application that displays three poems that _why composed.  Each poem has a header "0.0″, "0.1″ and "0.2″.  Only one poem is displayed on the screen at a time, the others are hidden under their header.  When the header of an undisplayed poem is clicked, the currently displayed poem is hidden and the undisplayed poem is shown using an accordian like swoop animation.  Very cool.

GUI-Layout

I think the most important thing to understand about this program is the layout of the GUI.  The GUI is composed of six stacks, three slots, and one flow.  Let me explain.  The main window is a flow.  To the main window, three slots are added each with two stacks (one for the header, one for the poem).  When the program is first started, all six stacks are added to the GUI window, but only four stacks are being shown at one time:  Three header stacks and one poem stack.  When the user clicks on a header item, the stack belonging to that header transitions to "fully shown" while the previous stack transitions to "hidden".

For example, clicking on the "0.2″ header hides the poem Stack 2 and Stack 4 while showing the poem in Stack 6.  We will look at how this is done below.

Open_Page Function

When a user clicks on a header item (0.0, 0.1, or 0.2), the open_page function is called and sent the stack item underneath the header that was clicked.  For example, using the picture above, if the Header '0.0′ were clicked, the open_page function would be sent Stack 2.

def open_page stack
 
  active = app.contents.map { |x| x.contents[1] }.
  detect { |x| x.height > 0 }
 
  return if active == stack
 
  a = animate 60 do
    stack.height += 20
    active.height = 240 - stack.height if active
    a.stop if stack.height == 240
  end
end

The first item of business in the open_page function is determining the currently active poem stack (the stack with the visible poem).  In our picture above, the currently active poem stack is Stack 6.  The app.contents.map function sends each slot in the GUI to the block of code to the right of the function call.  The slot is represented by the variable x.  Remember, each slot contains two stacks.  The first stack is the header stack.  The second stack is the poem stack.  We are, at the moment, only interested in the height of the poem stack which is the second item in the slot, thus x.contents[1]Detect is then called on that stack to see if the poem stack's height is greater then zero.  If it is, then it is the currently active poem stack and is returned to the variable entitled 'active.'

If the currently active poem stack equals the stack sent to the open_page function, then nothing is to be done and the function returns.  This functionality can be observed in the picture above.  If the header '0.2′ were clicked at this point, the poem under the '0.2′ header is already active, therefore there is nothing further to be done.

If, however, the header '0.0′ is clicked, an animation event is activated at 60 frames per second.  On each frame, Stack 2's height is increased by 20 pixels, while Stack 6's height is decreased by 20 pixels.  This continues until Stack 2's height is now 240 pixels and Stack 6's height is 0 pixels (or hidden).  This produces the fun accordion animation that you know and love.

Phew.

That was the most complex part of the code.  If you can understand that, you can for sure definitely understand the rest. I'm not going to go through it all, however, I am going to talk about a few places in the code that are clever or interesting.

More Ruby Fun

The first item I'd like to talk is not a function of Shoooes, but a function of Ruby that I had never seen before.  The page function is called, and two strings are sent to that function as the 'title' and 'text' variables.  All the text between <<-'END' and END is captured and sent to the 'text' variable formatting intact.  This is a great way of capturing a bunch of text whose formatting you want to preserve into a variable.

page "0.0", <<-'END'
There is a thought
I have just had
Which I don’t care to pass to
Anyone at all at this time.
 
I have even forgotten it now,
But kept only the pleasures
Of my property
And of my controlled mental slippage.
END

The first line of the page function is a cool trick for seeing if an array is initialized or not.  You simply OR it with itself.  If the @pages array already exists, @pages will be simply set equal to itself.  If it doesn't exist, however, @pages will be set to a new array.

@pages ||= []

Remember, if you have any more questions about the Simple-Accordian, snag the commented code.  It should answer most of your questions.

Written by codingwithoutcomments

August 21st, 2008 at 5:54 pm

The Not-So-Boring Guide to Subversion (Part 1)

without comments

And now a conversation between Present me and Past me.

Yo.  (Present Chris)

What's going on? (2003 Chris)

Not much.  Hey, what's with the Robot arms?

Oh.  These?  Yeah.  You were really into dancing the Robot back in 2003.  You thought it was hilarious.

Well you look dumb.  Stop.  It's definitely not cool to dance in the Robot in 2008.  Mouse ears are cool now.  And V-Neck tees.  Look into them.

Got it.  Hey, quick question.  If you could go back to, uh, me and give you err me one piece of career/programming advice.  What would it be?

Find a cute chick and marry her because you won't meet any more girls after college in your predominately male work-place.

Got it.  Jotting it down.  "Get married…"  OK.  Anything else?

Version Control, dude.

Wha..?  Version Control?  Why?

It's like time travel, dude.

…and, you're in love with it.

Welcome to the Not-So-Boring Guide to Subversion.

I created this guide because in the process of reading the Official Guide To SVN I feel asleep.  Three times. The following is the result of trying to keep myself amused enough to stay awake and learn Version Control  Which, I am told, is like Time Travel minus the Terminator nakedness.

Check-It-Out

To start, let's say you wanna work on an Open Source Project that you keep hearing all these kids talk about around the water cooler.  It's a really cool project too.  Lots of lasers.

Most of the files for open-source projects are stored in something called a Repository.  Everytime I hear the word Repository, I think Dungeon.  When I say Repository, you say Dungeon.  Repository.  (Dungeon).  Repository.  (Dungeon)  The Repository is the creepy, spooky, wet and dank place all the files are kept.

So, first of all, if you wanna get files out of the Reposoitory, you have to check them out.  Like library books.     Go ahead, try it.

$ svn checkout http://www.codingwithcomments.com/SubversionTest/trunk/

These files that you've checked out, are what they refer to in the "biz" as a Working Copy. Some secret files are kept in our Working Copy directory in a secret folder ominously named ".svn."  If you put a period before a folder name, it hides it.  In your folder preferences, you need only enable "show hidden files" to see these secret monstrosities.  These files help subversion keep track of all the unpublished and out-of-date files with respect to to all the folks who are publishing their changes.

$ svn checkout http://www.codingwithcomments.com/SubversionTest/trunk
A    trunk/ThreatenAnimal.rb
Checked out revision 1.

Two Ruby files.  Sweet.  What?  Did you think we'd have you checkout some Cobol?  Heck no.

Now type:

$ ls -A trunk
.svn  ThreatenAnimal.rb

Look, you can see the .svn directory!  Appending '-A' to 'ls' lets you see all the secret hidden files.  It's like your asking '-Aren't you going to show me all the secret files?"

Now run ThreatenAnimal.rb.

$ ruby trunk/ThreatenAnimal.rb
Stop Looking At Me Swan!

Adam Sandler is not a friend to animals.  OK, now open ThreatenAnimal.rb in your favorite text editor and change 'Swan' to 'Adam Sandler'.  My favorite editor is called 'Emacs Vim'  It's a special brew of the two best text editors lumped into one.  (This is a joke.  There is no such editor.  Some programmers find this sort of joke funny.)

Make a Commit-ment

So now you and ThreatenAnimal.rb have been going steady for awhile.  You've been on several dates, and you are even thinking about asking it to prom in a few weeks.  You are ready for a bigger commitment.  You are ready to 'commit' your changes to the repository.

$svn commit ThreatenAnimal.rb -m "Adam Sandler != funny"
Sending        ThreatenAnimal.rb
Transmitting file data .
Committed revision 5.

'-m' appends a commit note.  You should do this when you commit a file so everyone knows what changes you made.  When I decide to commit to someone, I write them a note.  "Do you want to be my girlfriend?  Check yes or no."  This way, they know what's up.

Note:  Each file doesn't have to be commited individually.  For example, if there was more than one file in the trunk directory, they could all be commited at once with a single command.

$svn commit trunk

I need an update, pronto!

Uh oh.  But there could be a problem.  Say you are working on this project with the dreaded Ebeneezer Scrooge.  Ebenezzer Scrooge checked out ThreatenAnimal.rb when you were still trying to decide if you wanted to make a commitment.  His TheatenAnimal.rb file still threatens swans instead of Adam Sandler.  Oh Ebeneezer, you're such a card.  Simply type,

$svn update
U  ThreatenAnimal.rb
Updated to revision 5.

The update command brings Ebeneezer's files up to date.  Ebeneezer is happy now.  So happy, he sends me a message on google chat, 'No, you still can't have a lump of coal.'  Oh frostbite!

Q and A

Question:  What's with all the revision numbers?

Answer:  Each time you make a 'commit' it updates something called a Revision Number.  These numbers start at zero and go to infinity.  Even If you 'commit' only one file in the repository, it creates a completely new file tree and updates the revision numbers of all the files in the repository.  It's all or nothing.  Think of it this way.  If you make a commitment to a girl (or a guy), you are making a commitment to not just the girl (or guy) but to their friends, parents, and pets.  It's an all or nothing deal, right?  You can't just take one without taking all the rest.  This sucks, I know, but that's why these Suversion guys refer to it as an Atomic Transaction.  Because you feel like you've just been nuked.

There's a picture of how this works in the famous SVN book.  It's pretty boring and drab but it gets the point across I suppose.  0 through 3 are the revision numbers.

The Repository!
The Repository!

However (comma) although all the revision numbers are updated for all the files in the Repository, your Working Copy (the copy of the project on your hard-drive) contains Mixed revision numbers.

Scandalous Revision Numbers

OK.  Let's see an example shall we?  Let's say you've got three files, you've recently done an svn Update, and all the files in your Working Copy and Repository are at Revision 5.

BlackBear.rb           (Revision #5)
Santa.rb                 (Revision #5)
ElephantMan.rb      (Revision #5)

We then make a change to ElephantMan.rb and Commit him to the Repository (where every Elephant-type man deserves to go).  Just like we talked about, all the files in the Repository are at Revision #6.

BlackBear.rb           (Revision #6)
Santa.rb                 (Revision #6)
ElephantMan.rb     (Revision #6)

BUT, the files in your Working Copy have MIXED revision numbers.

BlackBear.rb           (Revision #5)
Santa.rb                 (Revision #5)
ElephantMan.rb     (Revision #6)    <== the oddball

This is NORMAL.  In fact, sometimes you want to purposefully backdate certain files of your Working Copy to an earlier revision.  This makes Subversion, you know, kind of like a Time Machine.  To understand the Time Machine, I suggest you rent '12 monkeys.'  It is the definitive movie on Time Travel.  Whatever you do, don't watch the Back To The Future movies.  These are silly and Oedipal.  How can those two adjectives co-exist?  Only with the help of Steven Spielberg.


Just Remember: Commit != Update

A Commit does not equal an Update.  An Update doesn't equal a Commit.  You can Commit all day long, but until you run an update, you aren't going to incorporate anyone else's Commit(s) into your Working Copy.

Written by codingwithoutcomments

August 16th, 2008 at 10:17 am

Best Blogging Options for Programmers / Source Code Formatting

with 9 comments

Hello! (in french)

Hello! (in french)

I think everyone that starts blogging inevitiably writes things like, "This is my first blog, um, i don't know what to say, um, oh this is awkward isn't it.  Hello world!"  But, unlike everyone, I do actually have something (somewhat interesting) to say.  Which is strange, but nice I suppose.

The idea for this post started when I was reading a post on Stackoverflow, the new joint venture between Joel Spolsky and Jeff Atwood, entitled 'How you can tell you are ready to start your own blog?'

The post went as follows:

Hi, I'm curious whether I should start my own blog or not.

I've been working as a programmer for 3 years and have some good and bad experience I can share. On the other hand I'm not sure I will be able to post very often (maybe even less then one time per week).

They say writing a blog will improve your writing skill and it seems appealing to me. I've to admit sometimes I've a problem to write down my ideas in a short clear way so people can understand them easily. But I don't want to write for the sake of writing. I think that blog helps me only if there will be some readers and therefore some comments. In order to have readers I've to put some interesting stuff there pretty regularly, haven't I?

So how can you tell when it's time for one to start blogging?

The replies are now legendary.  Besides improving your writing skills, the reasons to start a blog as a programmer are quite numerous.

Why You Should Blog As a Programmer

The mere act of writing your thoughts and actions down is a form of teaching.  Blogging cements the knowledge you have acquired in your brain 8.9 times better then just mere-programming or even verbally explaining something to someone.

Steve Yegge writes in 'You Should Write Blogs',

"…that blogging is a source of both innovation and clarity. I have many of my best ideas and insights while blogging. Struggling to express things that you're thinking or feeling helps you understand them better."

Jeff Atwood talks about in his podcast how he doesn't feel like he has actually done any work at all if he hasn't documented it and put it in the public sphere.  Being so exposed, he knows he is accountable to the thousands of people who read his blog.  This, in turn, causes him to produce better quality work (he hopes).

When blogging as a programmer, you are creating a documented public portfolio of what you are working on, a resume that is more then a few lackluster pages in Word with various haphazard skills and, in my case, a not so long job history as well as a reference for your future projects.

But better then that, simply the act of blogging can lead to success and fame.  In how to achieve blog success in one easy step, Jeff Atwood writes about his success from blogging,

I won't say I got my job here at Vertigo back in 2005 because of this blog, but it was definitely a factor. I was interviewed on .NET rocks, and I've been interviewed online not once but twice. I've been invited to speak at conferences. I am approached for book deals every few months. I exchange email regularly with Steve McConnell, one of my programming idols as a young adult, and he once asked me for advice on blogging. Joel Spolsky actually recognized me and invited conversation when I attended the Emeryville leg of his world tour. Charles Petzold sent me, completely unprompted, a signed copy of his latest book. People offer to send me incredibly cool free swag on a regular basis.

Jeff goes on to say that he thinks that blogging is "the most important thing I've ever done in my entire career."  Wow.

So, inspired to the teeth by reading all of the above, I set out to start my own blog.  I went to google, clicked "create blog" at Blogger, clicked "Write New Entry," and started working on a piece about, i don't know,  the Template Pattern in Ruby or something.  I pasted some code into my blog, moved my mouse up to the formatting options and stopped dead in my tracks.

There was no Code Formatting option!

Shame shame know your name Google.  How can you write a programming blog without code formatting options?  (Answer: Black Bear).  I realized this was a question for the hive mind so I asked the good folks at Stackoverflow what is the best blogging host for programmers/code formatting?  The results were wide and varied.

Blogging Options

Most people seemed to agree that Wordpress was the best overall blogging platform in terms of options and flexibility.  These same people stated that one is better off self-hosting wordpress or using a hosting provider and getting a domain name rather then using the hosted wordpress (Wordpress.org vs. Wordpress.com).  Self-hosting has a couple of main advantages as stated by Christain:

  • You will be the master of your domain name: when you want to change hosting company or software, you will be able to do so. You don't want to change your domain name when you have thousands of readers and a Google PageRank of 5.
  • You will be able to customize your software (with little effort) to add the many plugins available.

I decided to go with Wordpress and bought a one year webhosting package from DreamHost (recommended by wordpress) for a little under $100 for like a bagillion gigs of space and bandwith.  Plus, setting up wordpress on Dreamhost was insanely easy.  They have a one-click installer.  It took 2 minutes.  They also have a one-click installer for Subversion which i found cool.  You are now viewing the results.

Code Formatting Options

1.  If using wordpress, the WP-Syntax plugin provides clean syntax highlighting using GeSHi — supporting a wide range of popular languages. It supports highlighting with or without line numbers and maintains formatting while copying snippets of code from the browser.

Below is an example of GeSHi formatted code in Ruby using the wordpress plugin,

class Report
  def initialize
    @title = 'Monthly Report'
    @text = ['Things are going', 'really, really well.']
  end
 
  def output_body
    @text.each do |line|
      output_line(line)
    end
  end

Geshi isn't limited to wordpress, but can be used to "highlight code on ASP pages, numerous blogs, wikis and forums."

2.  Use Windows Live Writer with the Insert Code plugin. The problem with this option is that you are limited to blogging on a Windows (sic) Machine, and it only formats the the following languages:  C#, HTML, MSH, JavaScript, Visual Basic and TSQL.

3.  SyntaxHighlighter is a Javascript based Code Formatting mechanism that can easily integrate into most blogging systems.  It supports the following languages: C++, C#, CSS, Delphi, Java, JavaScript, PHP, Python, Ruby, Sql, VB, XML/HTML.  Ellis Web posted a great article on Using Syntax Highlighter to Format Code in Wordpress.

4.  If using the blogging engine Chyrp, Geshify or Feather can be used for Code Formatting.

5.  Mango Blog and BlogCFC both support code blocks out of the box.

6.  CodeHTMLer is a simple program that translates plain text code into a colorized HTML version of the code.

7.  If you use TextMate in Mac OSX, BitButter has a great post on how to display your TextMate code (formatting included) in WordPress.