Ruby Quine Example

Posted by ben on June 24, 2010

I was recently challenged to write a quine in the language of my choice. If you are unsure what a quine is you can find out from http://en.wikipedia.org/wiki/Quine_(computing). However basically in our case it is a piece of code that when executed creates a copy of itself. This copy can then be executed and ad infinitum.

There are some official rules about how a quine should be implemented:

  • A quine must not take any input, as this would allow the source code to be fed in from the keyboard.
  • Following on from the previous rule a quine, should not open it’s own file and display it’s contents.

Anyway here is my solution in Ruby…

    lambda{|x| puts x + x.inspect}.call "lambda{|x| puts x + x.inspect}.call"

Here is a brief description of what is happening. The lambda creates an anonymous function that takes one parameter and outputs it’s value

Officially I think passing a value into the lambda x attribute violates one of the rules – but non-the-less it is quite a clear example and may be useful to get an idea of how a quine works.

Links

Here is a list of interesting links that might help, good luck:

Code Kata Four Exercise – A Ruby Solution 2

Posted by ben on May 09, 2010

I recently did code kata 4 (data munging), and here is my solution to the problem. Like anything it can be improved but I think it is relatively simple to understand and yet flexible enough to work for a number of different formatted .dat files.

The premiss is to write a program that will work out the deltas ( difference ) between two columns in .dat files and return the lowest values.

These .dat files have different numbers of columns and these columns can be in different order. The two .dat files used for this program supplied weather temperature ranges and football (soccer) result scores.

Anyway here is my solution in the Ruby language and a description of how it works:

# data_processor.rb

module DataProcessor

  def process_dat(filename, regex=/^\s*\d+\.?\s+/)
    items = []
    IO.foreach(filename) do |line|
      if line =~ regex
        num, max, min = yield line
        delta = max.to_i - min.to_i
        items << [num, delta] if items.size == 0
        current_items = items[0][1]
        if delta <= current_items
          items.clear if delta < current_items
          items << [num, delta]
        end
      end
    end  
    items
  end

end

if __FILE__ == $0

  include DataProcessor

  puts "-------- Weather  --------"
  list = process_dat('weather.dat') { |line| tokens = line.split(' ') }
  list.each { |item| puts "Lowest Day:#{item[0]} Delta:#{item[1]}"}

  puts "\n-------- Football --------"
  list = process_dat('football.dat') { |line| tokens = line.split(' ');[tokens[1], tokens[6], tokens[8]] }
  list.each { |item| puts "Team:#{item[0]} Delta:#{item[1]}"}
end

The code above was created as a module as this will allow the process_dat method to be mixed-in to other objects, allowing these objects to execute the code without having to instantiate another class to get this functionality.

The process_dat method takes a filename and an optional regular expression. The regular expression (regex) is used to find the data in the text file for processing. In this case any line that starts with 0 or more spaces followed by at least one number and then an optional ‘.’ after that number followed by at least one space. This regular expression could have been used to extract the data from each row as well – but it actually became much easier to simply split each row and tokenise it around a space, as we are processing space separated files.

Using the IO.foreach method will iterate over each line of the .dat file allowing the logic to process that line. This is much more memory efficient, as only one line is loaded into memory at each iteration of the loop – thus allowing this method to process very large data files.

Next the method checks to see if the line matches the regex (if line =~ regex) if it does it can be processed.

Processing each line is handled by a Ruby block, (as a yield statement is used), in the “weather.dat” case the block simply splits the line around a white space. In the “football.dat” case the block splits the line around the white space but re orders the returned columns. Incidentally it is useful to know that if the number of tokens in the array exceeds the number of possible assignments (num, max, min = yield line, where yield line returns a 10 item array for instance) Ruby conveniently ignores the other values after assigning the first lot.

The next couple of lines simply calculate the delta and assigns it to a temporary array (items) if items is empty. The items array simply holds the lowest values as a collection of lowest values with the same value. Note that the items array is an array of arrays. The item in the items array consists of a number and a delta.

Finally we get the lowest item from the items array and check to see if the current line delta is lower if it is, clear the items array and add this new item. If it equals the same value simply add this item to the items array. Thus the items array will contain the same lowest values.

I hope you find this helpful – if you have an alternative solution, why don’t you add it to the comments at the bottom.

18 Useful bash scripts for web developers 45

Posted by ben on June 05, 2009

Using bash scripts to become a more efficient web developer

Here are a few scripts, that I find really useful for speeding up my web development time.

I’ve been building up this list as I needed to use them – so they maybe a little raw.

For example often clients send me images with filenames that don’t match my naming standard, so running the appropriate script really helps keep me focussed on the job in hand and not waste too much time reformatting filenames etc.

Finally if you have any useful little bash scripts why don’t you add them to the comments below?

Bash script to append a .txt extension to a filename

Iterate over the current directory, get all files with .log and append .txt to the end of the entire filename:

for i in *.log*; do mv "$i" "$i.txt"; done

Script to make filenames lowercase

Converts all the file names in a directory and converts them to lowercase.

echo version:

for i in *.log*; do echo mv \"$i\" \"`echo $i| tr [A-Z] [a-z]`\"; done

real version:

for i in *.txt; do mv "$i" "`echo $i| tr [A-Z] [a-z]`"; done

Quick note on how to use grep to search for a string in file

-o print Only the matched parts of a matching line, with each part on a separate line. -H print the filename for each match. -n prefix each line of output with the 1 based line number. -R, -r recursively read all files under subdirectories.

grep -oHnr "some pattern"  *.txt

{txt,log} this globs the file extensions together. 2>/dev/null this passes all errors to a blackhole, so that they won’t be displayed.

grep 123741 ./adapter_logs/*.{txt,log} 2>/dev/null

Find all occurrences of 123741 in all .txt and .log files in all subdirectories.

for i in 'find . -type d'; do grep 123741 $i/*.{txt,log}; done 2>/dev/null

List all files that match this regular expression in the current direcory

All files with the number 5 in their name.

ls | grep -e .*5.*

Bash script to check whether a tag exists in a subversion repository

svn ls http://www.mysvnserver.co.uk/myproject/tags | grep mytag-0.7.0.1/

The [ ] is known as a Test, by default it tests integers Also to end an if statement you use fi

if [ 1 = 1 ] ; then echo YES; else echo NO; fi

if [ "`svn ls http://mysvnserver/mysvnrepository/myproject/tags | grep R-9.20.400.0/`" = "R-9.20.400.0/" ]; then echo YES; else echo NO; fi

Note need the / in the evaluation part of “it-0.9.0.7/”, don’t really need it in grep it-0.9.0.7/

$ if [ "`svn ls http://www.mysvnserver.co.uk/myproject/tags | grep it-0.7.0.1/`" = "it-0.7.0.1/" ]; then echo YES; else echo NO; fi

Quick note on how to increment a variable, in a bash script

j=0; j=$(($j+1))

incrementing in a loop

j=0;for i in *.txt; do echo "some_file_"$j".txt"; j=$(($j+1)); done

Using a bash for loop to list all text files and append whoopee

for i in *.txt; do echo $i"whoopee"; done

Change all filenames to be a specific incremented name, starting from file 16

j=16;for i in *.jpg; do mv "$i" "gallery_"$j".jpg"; j=$(($j+1)); done;ls

Script to loop through all .txt filenames and make them lower case

for i in *.txt; do mv "$i" "`echo $i| tr [A-Z] [a-z]`"; done

Get all JPG files and create the appropriate HTML list tags for them and add them to a file

Create an HTML version:

for i in *.jpg; do echo "\t<li>\r\t\t<img src='images/$i' alt='' />\r\t</li>"; done > list_items.html

Create a HAML version:

for i in *.jpg; do echo "\t%li\r\t\t%img{ :src => 'images/$i', :alt => '' }\r"; done > imgs.haml

Batch change a misspelled filename of certain files, using string replacement

for i in aples*.jpg; do mv $i ${i/aples/apples} ; done

Script to batch create files based on filenames in a file

Create a file called something like “my_files.txt” with the following content:

archive_error_112480_0040.txt archive_error_114390_0043.txt etc…

Commands:

for i in `sed -n -e 'p' my_files.txt`; do mkdir a_test/$i; done
or
while read x; do touch $x; done < my_files.txt
or
cat my_files.txt | xargs touch
(xargs passes each line as an argument into EACH touch)

Using bash Expansions, and allow escapes

-e is an undocumented flag that allows escapes Expansion ${command/parameter/substitution} everything else needs to be escaped.

echo -e ${PATH//\:/\\n}

Executing a .bash_script after making changes

source .bash_profile
or
. .bash_profile

NB: you can ‘include’ other bash .sh scripts in a .bash_profile file by using ’source’ or ‘.’

Quick tip on using curl for downloading files off the web

Use -O to name the remote file, curl will save it locally but remove the rest of the path.

curl -O http://rubyforge-files.ruby-forum.com/rubygems/rubygems-0.9.0.tgz

Bash command for testing the existence of files and directories

If a directory does NOT exist create it

[ -d "/var/cache/git" ] || mkdir /var/cache/git

If a file exists echo a message:

[ -f "./new_file.txt" ] && echo "its there"

Bash command to remove spaces from filenames

for i in *.html; do mv "$i" "`echo $i| tr -d ' '`"; done

replace spaces for underscores

for i in *.html; do mv "$i" "`echo $i| tr ' ' '_'`"; done

Vim regex to replace spaces in images file names of ah HTML page

:%s:\(images\/\)\(\w\+\)\s\(\w\+\.jpg\):\1\2_\3:g

Copy text to the clipboard

echo 'hello world'|pbcopy
cmd + v

Conclusion

Some of these are quite basic but useful none-the-less, please add your own to the comments below. Many thanks, and good luck.

Updated…

Script function for .bash_profile to cd to the last opened finder location

This is a script written by a colleague. James Power. Add the following function to your .bash_profile in Apple OSX. Now open a directory in Finder, then open terminal and type cdf, your terminal will now change directory to the same one as the last Finder opened.

# function to change directory to the one set in the last opened finder.
cdf () {
   currFolderPath=$( /usr/bin/osascript <<"         EOT"
       tell application "Finder"
           try
               set currFolder to (folder of the front window as alias)
           on error
               set currFolder to (path to desktop folder as alias)
           end try
           POSIX path of currFolder
       end tell
            EOT
   )
   echo "cd to \"$currFolderPath\""
   cd "$currFolderPath"
}

Also for a much more comprehensive list of commands check out: http://www.commandlinefu.com/commands/tagged/34/bash

Ruby Rush command-line tool

If you use Ruby maybe check out Rush, it allows you do use Ruby in a bash command-line like way.

Chrome is a Desktop Web Application platform 5

Posted by ben on September 04, 2008

Google Chrome is not just a browser

Google Chrome was launched a few days ago on the 2nd September 2008, since then there has been much hype and articles written about it. So what is it? Well, Wikipedia describes it: “Google Chrome is a free and open source web browser developed by Google.”, however it is more than that.

It comes dressed as a web browser but is actually a Desktop Web Application platform. It facilitates the creation of Web Applications that are desktop like in functionality. These Web Applications will, be much more responsive, secure and stable than the previous generation of web applications because these new technologies are forming a suitable infrasructure.

It’s one of the technologies ushering in a new era for the Internet.

I wrote an article recently that describes how these technologies are laying down foundations for applications should use the web: Desktop web applications using SproutCore/

Why is Chrome significant

Recently a number of the big Internet centred companies have been making strides to enable the next generation of Web Applications.

Adobe with its AIR technology, Microsoft with Silverlight, Apple with its endorsement of the SproutCore JavaScript framework, and Google, until this announcement, Gears.

The problem is none of these offerings is perfect, and some of them are very much propietary, tying users into their technology.

The problem Google has is that Gears is actually a very good product, but why would anybody download and install it if there aren’t may web sites using it? At the moment this is an additional step resulting in the fact that most users have no compelling reason to install it. In a nut shell nobody is using it.

However with Chrome Google is able to hedge its bets, it has merged several standalone technologies into one very capable and pleasing package.

  • It has an awesome JavaScript engine enabling JavaScript to approach Desktop Application speeds.
  • It has Gears enabling developers to create offline applications that can interact with your desktop.
  • It can open a Web Application directly in its own window, without any of the traditional browser tool bar and menu overheads. Making Web Applications look like Desktop Applications.
  • It has added stability by making each tab a separate process, essentially each tab behaves like its very own browser.
  • It is secure in that it has been designed from the ground up following proven security models, such as sandboxing.
  • Its elegant, meaning that it feels small, light and fit for purpose. It has taken some leaves out of Apple’s book and made the UI simple yet powerful.

Chrome is OpenSource and follows standards

This next era of the Internet is going to very busy. Everyday there are vast numbers of web pages and Web Applications created, and with this colosal amounts of data and information to sift through.

For an individual it is becoming harder and harder to focus and extract the useful information from all that data. In essance attention is a currency and with all these web sites and applications vying for our eyeballs how do we as users filter the wheat from the chaff?

That part of the Internet isn’t completely written yet but for certain, by following Web Standards and by incorporating OpenSource technologies we are laying the foundations for future tools to help us do this. Chrome is one such OpenSource technology.

Chrome needs to follow standards as these will pull it along and it will evolve into something very powerful. Even if it doesn’t some of its components may find there way into some technology that does. I dare say that Google will have a finger in that pie no matter. As a result it is a win win situation for Google.

This also highlights the point that Microsoft’s Internet Explorer browser is gradually getting left behind. Admittedly standards aren’t followed by all these companies but Microsoft has certainly been more relunctant to endorse them.

JavaScript is a key web technology

JavaScript is old, it appeared in the early browser wars and there hasn’t been any significant changes since. Its been buggy, doesn’t scale well, and there are differences on just about every browser implementation, but it is everywhere.

Recently, with Web 2.0, JavaScript has had a bit of a resurgance and some very useful frameworks have emerged which mitigate the implementation issues and improve its stability. However up until recently it has been slow. Too slow to be useful in terms of creating sophisticated Desktop like Web Applications.

It seems that in order to compete in the new Desktop Web Application arena companies need to implement a fast JavaScript engine. Apple’s Safari is implementing SquirrelFish, and Firefox is implementing TraceMonkey and now Google has created V8.

John Resig has done a comparison of the relevant JavaScript engines and it seems that V8 is very fast. Matthieu Riou says that V8 is closer to a compiler than a traditional VM. It takes JavaScript code and converts it into low level byte code. It is still early days but we can expect this performance to keep improving.

Desktop Web Applications, Slickening the Web.

This era of the Internet is seeing a ’slickening of the web’. Web Applications are becoming more Desktop like. Platforms like Chrome are only going to push us faster along this path.

We can expect to see more applications like Gmail, MobileMe, GoogleMaps, GoogleDocs, etc. but Chrome puts Google very definately in one of the front seats for the future.

Its not fully there yet as its still missing features but it will evolve quickly. Google has vast resources and is able to test the browser against millions of web sites before it ever sees a user. This will only help to refine and improve it.

With Google Chrome, the Web is changing up a Gear.