Not the best way to start the day…

Misc 2 Comments »
For some reason this morning, I must have had one of those revelation moments, I woke up thinking about certainties. 

There are only 3 things that are certain in life: death, taxes, and browser incompatibilities…

I think I need a break….

Installing and managing edge Rails

Rails, Ruby 1 Comment »

Great article here:

http://www.sitepoint.com/blogs/2006/07/11/installing-and-managing-edge-rails/

How to stop webrick from the command line

Rails, Ruby 2 Comments »

To create a bash file to stop webrick.

In a terminal type gedit stopWebrick and add the following to the contents of the file and save it.  Give the file execute permission with chmod of using the file properties in nautilus.

#!/bin/bash
kill -9 `ps -o pid,cmd –no-heading -p $(pgrep ruby) | grep script/server | awk ‘{print $1}’`

This will kill the first ruby process it finds running as script/srever

Run it as needed.

UserSumChallenge Module

Rails, Ruby, JavaScript 1 Comment »

The following module is my first ever Ruby/Rails Module.

The UserChallenge module will create a simple random sum, that can be prompted to the user for solving as part as your authentication scheme during a registration process.
Simply create an instance of UserSumChallenge or UserSumImageChallenge and store against the user session. If you use the image challenge, call render to create the image otherwise just add the question attribute to your output.










# UserChallenge provides several mechanisms to aid in establishing a real user is on the end of a submit

# Typically used for user registration processes or commenting, the UserChallenge module will allow you to provide

# a challenge question and validate the repsponse.

# Mixins include

#       * SumChallenge - provides a simple arimethetic sum to be solved

#       * RandomTextChallenge - supplies a random string of characters

# Supporting Classes include

#       * SumTextChallenger - Class that will provide a question as a text string

#       * SumImageChallenger - Class that will create a png image with the sum in it

#       * RandomTextChallenger - Class that will provide a random text string

#       * RandomTextImageChallenger - Class that will create a png image with the random text string in it

module UserChallenge

    

    # This module creates a challenge that is a basic sum, expecting the respose to be the sums result, e.g. 2+6

    module SumChallenge

        #Initailizes the challenge to a sum

        #optionally specify the max values for the left and right 

        def createChallenge(lMax=10, rMax=10)

            lValue = rand(lMax)

            rValue = rand(rMax)

            @solution = lValue + rValue

            @question “#{lValue} + #{rValue}”

        end

        # checks the value passed in against the expected result    

        def checkResponse(value)

            return (@solution == value.to_i)

        end

    end

    # This module creates a challenge that is a series of random characters in a specified range, expecting the respose to be the same string

    module RandomTextChallenge

        #Initailizes the challenge to a sum

        #optionally specify the number of characters to generate and the range of characters to choose from

        def createChallenge(count=6, chars = ‘a’..‘z’)

            @question “”

            count.times do

                index = rand(chars.entries.length-1)

                @question += chars.entries[index]

            end

            @solution @question

        end

        # checks the value passed in against the expected result    

        def checkResponse(value)

            return (@solution == value.to_s)

        end

    end

    

    # A simple class that generates a sum challenge in text form

    class SumTextChallenger

        include SumChallenge

        

        # the sum question as a string

        attr_reader :question

        # the solution as an integer

        attr_reader :solution

        

        def initialize()

            createChallenge()

        end

    end

    

    # A class that generates a sum challenge in image form

    class SumImageChallenger

        require “RMagick”

        include SumChallenge

        # the sum question as a string

        attr_reader :question

        # the solution as an integer

        attr_reader :solution

        

        def initialize()

            createChallenge()

        end

        

        # returns an image blob with the sum question layered ontop of the specified background

        def render(backgroundImageUrl)

            background = Magick::Image.read(backgroundImageUrl).first

                

            croppedImg = background.crop(0,0,128,28)

            

            text = Magick::Draw.new

            text.annotate(croppedImg, 1282800@question) {

              self.gravity = Magick::SouthGravity

              self.pointsize = 24

              self.stroke = ‘transparent

              self.fill = ‘#0000A9

              self.font_weight = Magick::BoldWeight

            }

            

            croppedImg = croppedImg.blur_image

            return croppedImg.to_blob

        end

    end

    # A simple class that generates a random text challenge in text form

    class RandomTextChallenger

        include RandomTextChallenge

        

        # the sum question as a string

        attr_reader :question

        # the solution as an integer

        attr_reader :solution

        

        def initialize()

            createChallenge()

        end

    end

    

    # A class that generates a random text challenge in image form

    class RandomTextImageChallenger

        require “RMagick”

        include RandomTextChallenge

        # the sum question as a string

        attr_reader :question

        # the solution as an integer

        attr_reader :solution

        

        def initialize()

            createChallenge()

        end

        

        # returns an image blob with the sum question layered ontop of the specified background

        def render(backgroundImageUrl, width=128)

            background = Magick::Image.read(backgroundImageUrl).first

            

            croppedImg = background.crop(0,0,width,28)

            

            text = Magick::Draw.new

            text.annotate(croppedImg, width, 2800@question) {

              self.gravity = Magick::SouthGravity

              self.pointsize = 22

              self.stroke = ‘transparent

              self.fill = ‘#0000A9

              self.font_weight = Magick::BoldWeight

            }

            

            croppedImg = croppedImg.blur_image

            return croppedImg.to_blob

        end

    end

end


Here is a simple controller that uses a ImageChallenge.  Notice the background being supplied to the render method

class MainController < ApplicationController require “UserChallenge” def welcome @challenge = UserChallenge::UserSumImageChallenge.new session[”uc”] = @challenge end def image storePath = “/home/user/path” filename = storePath + “/Camouflage.png” challenge = session[”uc”] session[”uc”] = nil send_data challenge.render(filename), :filename => “confirm.png”, :type => ‘image/png’, :disposition => ‘inline’ end end

Installing RMagick on Ubuntu

Ruby No Comments »

Taken from the rubyonrails wiki, for my reference:

If you need RMagick support for your web app, your going to need to install ImageMagick and RMagick.

sudo apt-get install imagemagickdpkg -l | grep magick

This will install the most current imagemagick and then

list the ‘magick’ packages installed. Look for what version of
libmagick got installed and make sure you specify THAT version number when you install libmagick-dev.

sudo apt-get install libmagick9-devsudo gem install rmagick

After a lengthy build process, you’re ready to edit images in ruby!

Raaum’s Rails Reader

Rails 1 Comment »

Rails Documentation for the Working Developer

http://rails.raaum.org/

Installing Ruby and rails on Ubuntu Feisty

Rails, Ruby 1 Comment »

The image “http://www.rubyonrails.org/images/rails.png” cannot be displayed, because it contains errors.

Found these instructions at http://www.aptana.com/forums/viewtopic.php?p=10640

Blogging to ensure I have a copy, credits go to janmartin.

Lets start with a fresh Ubuntu Feisty Fawn 7.04 installation:

  • sudo apt-get install build-essential
  • sudo apt-get install sun-java6-jdk
  • sudo update-java-alternatives –list
  • sudo apt-get install ruby irb ri rake rdoc ruby1.8-dev rubygems
  • sudo apt-get install libmysql-ruby mysql-server
  • sudo gem update –system
  • sudo gem install rails –include-dependencies

Some tests:

  • ruby –version
  • rails –version
  • mysql –version
  • gem list

END of command line installation

Download
Aptana + Rails (Linux).
Extract it into ~/aptana

Follow these instructions:
# Open up Aptana, and Navigate to the Help > Software Updates > Find and Install menu.
# Select “Search for new features to install”, click “Finish”
# Select “Ruby on Rails Development Environment”, click “Finish”
# Select the Ruby on Rails Development Environment feature.
# Continue through the dialog boxes until complete.

Follow these instructions:
http://www.aptana.com/forums/viewtopic.php?t=1397

Configure:
Menu -> Window -> Preferences

Rails -> Configuration
Rails path: /usr/bin/rails
Rake path: /usr/bin/rake

Ruby
Installed interpreters:
/usr

Ri/rdoc
RDoc path:/usr/bin/rdoc
Ri path: /usr/bin/ri

Finished!

Powered by ScribeFire.

Ruby Class Cheat sheet

Ruby, JavaScript 1 Comment »

The following is my ruby class cheat sheet, aimed at developers new to ruby and rails. 

class MyClass                   #class declaration, notice the capital letter as this is a Constant
    attr_reader :readOnlyProperty, …        #shortcut to save writing a property getter
    attr_writer :writeOnlyProperty, …       #shortcut to save writing a property setter
    attr_accessor :readWriteProperty, …     #shortcut to save writing a property setter and getter

    def initialize              #class initialization method
        @instanceVar=1          #instance variable, available throughout an instance of the class.
        @readOnlyProperty=2    
        @writeOnlyProperty=3
        @readWriteProperty=4
    end

    def instanceVar             #property getter
        @instanceVar            #return the value of the instance variable
    end

    def instanceVar=(value)     #property setter
        @instanceVar = value    # set the instance variable to the passed in value
    end

    def instanceMethod          #instance method, available to all instances, this is the instance
    end

    def MyClass.classMethod     #class method, only accessible via the class, this is the class
    end

    CLASSCONSTANT = [”a”,”b”,”c”] #constant defined by the class accessible by all instances note its in uppercase

end

I hope you have found this useful.  If you have anything to add please comment.

Going loopy with JavaScript

JavaScript 2 Comments »

I am in the middle of writing a JavaScript tree that can handle 100s of thousands of nodes in the tree and needed to see if I can optimize the code.  Trying to optimize the loop iterations for array objects, I put together a test case to time the efficiency of various different types of loops in JavaScript.

The test

Create an array of 1 million numbers 0 to 1 million, for each of the loop tests, increment a counter then display it at the end of the iterations.

The test covers the following loops:

  1. ForLoop - standard for loop accessing the length of the array in the iterator
  2. ForLoopLocalCount - standard for loop, accessing the length of the array stored in a local variable before the iterator
  3. ForLoopLocalCountAndIterator - standard for loop accessing the count and the iterator from local variables
  4. ForInLoop - standard For In loop
  5. ForInLoopLocalItem - standard For In Loop, but declaring the iterator variable locally first.
  6. WhileLoop - While loop iterator accessing the length at each iteration
  7. WhileLoopCountFirst - while loop but storing the length of the array in a local variable before the iterator.

 

var loopTest = {
    itemCount : 1000000,
    items : [],
    
    initArray : function()
    {
        for(var x=0; x < this.itemCount; x++)
        {
            this.items.push(x);
        }
        console.log(this.items.length);
    },
    
    forLoop : function()
    {
        var total=0;
        for(var i=0;i < this.items.length; i++)
        {
            total ++;
        }
        console.log(total );
    },
    
    forLoopLocalCount : function()
    {
        var total=0;
        var count = this.items.length;
        for(var i=0;i < count; i++)
        {
            total ++;
        }
        console.log(total );
    },
    
    forLoopLocalCountAndIterator : function()
    {
        var total=0;
        var count = this.items.length;
        var i = 0;
        for(i=0;i < count; i++)
        {
            total ++;
        }
        console.log(total );
    },
    
    forInLoop : function()
    {
        var total=0;
        for(item in this.items)
        {
            total ++;
        }
        console.log(total);
    },
    
    forInLoopLocalItem : function()
    {
        var total=0;
        var item = null;
        for(item in this.items)
        {
            total ++;
        }
        console.log(total);
    },
    
    whileLoop : function()
    {
        var total=0;
        var i = 0;
        while(i<this.items.length)
        {
            total ++;
            i++;
        }
        console.log(total );
    },
    
    whileLoopCountFirst : function()
    {
        var total=0;
        var i = 0;
        var count = this.items.length;
        while(i<count)
        {
            total ++;
            i++;
        }
        console.log(total );
    },
    
    runTests : function()
    {
        this.initArray();
        this.forLoop();
        this.forLoopLocalCount();
        this.forLoopLocalCountAndIterator();
        this.forInLoop();
        this.forInLoopLocalItem();
        this.whileLoop();
        this.whileLoopCountFirst();
        console.log(“Complete.”);
    }
}

 

The test was profiled using the firebug profile option and run in Firefox 2.0.0.4 on a Dual Core Pentium 3.2Ghz machine with 3Gb of ram.

 

Results & Conclusion

The test results are shown in the table to the right. So what can we conclude from the results?

  • Don’t use a For In loop.  There is a small increase in performance if you allocate the item variable outside of the loop, but it is still up to 31 times slower than using a for or while loop.
  • Always ensure that the count (used in the loop exit test) is stored in a temporary variable outside of the iterator i.e. rather than calling array.length in the iterator exit test.
  • When local variables are used to store the iterator and count, a for loop performs the same as a while loop.  One would assume that the JavaScript.
  • In a For loop, declaring the iterator variable outside of the loop actually slows the iteration down! This I did not expect.

Firebug - Console options

JavaScript 1 Comment »

Firebug, the ultimate javascript debugger for firefox, automatically creates a “console” object that has various methods that can be used to aid in debugging your javascript apps.

Full Documentation is here http://www.getfirebug.com/console.html

console.log() is the most used, with the ability to pass parameters and a formatted string.

One of the nice things is, if you log an object it displays all the objects properties as well.

For performance testing console.time(id) and console.timeEnd(id) are very useful.

consolt.trace() will even dump the full stack at the point it is called.

 

If you haven’t got firebug, it’s a must if you are developing with firefox.  Go get it here

WP Theme &Design by minus19.com & Icons
Entries RSS Comments RSS Login