2013年5月3日星期五

Reverse a integer in haskell

Algorithm

1. Change a integer into string (actually it is a array of char)
2. Revese the string
3. Change the string into the number

Code

reverseNumber :: Int -> Int
reverseNumber n = read (reverse (show n)) :: Int

reverseNumbers l = map (reverseNumber) l

2013年4月3日星期三

Delayed a email for a specific time.

In the previous tutorial about a half year ago, I talked about how to create a simple delayed email with the great gem, delayed job. In the tutorial, the delayed duration is a constant for every object. But if you want to do this based on different condition, say the attribute of the delayed object. You can simply create a new Job Class and enquene the job with delay.


class NewJob 
  
  def initialize(job)
    @job = job
  end
  
  def perform
    Notifier.job_created(@job).deliver
  end
end

In the controller, you can enqueue the job to run at a specific time. I have used random number to simulate the random situation of the delayed time of each job.


delayed_time = Random.rand(1..10).minutes.from_now
Delayed::Job.enqueue(NewJob.new(@job) , :run_at => delayed_time)

2013年3月20日星期三

Finding row, column index of 2d array by giving the total number of item.

It's have been a long period of time I didn't update my blog.
I have found a interesting problem that I thought it's very complicated.

Supposed you are given a 2D array, the number of row and column is known.
The problem is to find the row, column index of nth item in the 2D array.

Solution:
total_item_index = n -1
row_index = total_item index / total_number_of_column
column_index = total_item_index / total_number_of_column

2013年1月2日星期三

Objective-C @property syntax

Oldest version

many libraries are like that!!!, you have to declare both instance variable, @property for getter and setter


    // header file:
    @interface Person :NSObject{
    NSString *name;
    }

    @property (strong, nonatomic) NSString *name;

    @end

    // implementation file
    @implementation

    // create getter and setter
    @synthesize name; 

    @end

Much more modern version

Many books or tutorials use it You don't have to decleare the instance variable, but you still have to @syntheize to get getter & setter


    // header file:
    @interface Person :NSObject

    @property (strong, nonatomic) NSString *name;

    @end

    // implementation file
    @implementation

    // create getter and setter
    @synthesize name; 

    @end

  

The newest version

supported by LLVM 4.0 or above Auto synthesize all getter & setter and to delcare instance varable All instance variables are with prefix _. You can access _name in the implementation file, while the other class access that variable by [object.name]

    // header file:
    @interface Person :NSObject

    @property (strong, nonatomic) NSString *name;
    @end

    // implementation file
    @implementation

    //.. auto @synthesize 

    @end

  

PS:

The syntheize instance variables just belongs to that class, if you want to inherit from that class, and to access the property as instance variabel in the sub class, you need to do the @syntheize in the sub class

    // header file of super class:
    @interface Person :NSObject

    @property (strong, nonatomic) NSString *name;

    @end

    // header file of sub class
    #import "person.h"
    @interface Teacher : Person

    @end

    // implementation file of sub class
    @implementation
    @synthesize name = _name // access public class's property as instance variable
    @end

  

2012年12月31日星期一

Base64Converter

Base64Converter

I have made command line Base64Converter which uses Ruby Standard Library to convert a image into Base64Encoded String.
Instead, I want it to have Standard output, I may improve it later :) Download here

Image upload from iOS to Rails (Part 3)

Review & Intro

In the previous tutorial, you will be able to create a Simple iOS application
and a simple rails application.
In this last tutorial, you will know how to send the image from iphone simulator to rails web application.

Principle for sending image

There are two common way to send image, one is to use the form data request, one is to use Base64 to encode the image data byte into ASCII code so that the encoded image data can be sent with JSON request.

Make connection from IOS

Assume you have put the library into the XCode project,
then import NSData+Base64.h into BIDViewController.m in order to get the ability to encode the image data.

  • Create a request with URL
  • Encode the Image data with Base64
  • Embed the encoded image data into JSON
  • set the JSON as the data of the reuqest
  • Make connection with the request owns JSON data

- (IBAction)sendImage:(id)sender {
    // Encode the Image with Base64
    NSData *imageData = UIImagePNGRepresentation(_imageView.image);
    NSString *imageDataEncodedeString = [imageData base64EncodedString];
    
    // Send Request to Server
    // Create the request with url
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:3000/accounts.json"]];
    
    // Add header value and set http for POST requeest as JSON
    [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:@"POST"];
    
    NSLog(@"Htttp Method%@ ", request.HTTPMethod);
    
    // Create dictionary key-value pair for transformming into NSData
    NSMutableDictionary *newAccount = [[NSMutableDictionary alloc]init];
    [newAccount setObject:_nameTextField.text forKey:@"name"];
    [newAccount setObject:imageDataEncodedeString forKey:@"icon_image_data"];
    
    NSLog(@"%@", newAccount);
    
    //transform the dictionary key-value pair into NSData object
    NSData *newAccountJSONData = [NSJSONSerialization dataWithJSONObject:newAccount options:NSJSONReadingMutableContainers error:nil];
    
    //let the NSData object be the data of the request
    [request setHTTPBody:newAccountJSONData];
    
    //create connection with the request and the connection will be sented immediately
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
    
    // the connection created is successfully
    if (connection) {
        _receivedData = [[NSMutableData alloc] init];
    }
}

Receive the data in the connection

The prevous step only made the connection to the URL, the controller have to owns a NSMutableData in order to holds the data received from the connection.

@interface BIDViewController  ()
    @property (strong, nonatomic) NSMutableData *receivedData;
@end

// delege meethod of NSURLConnection
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [_receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    
    
    // parsing the return JSON Sting
    /* {"created_at":"2012-12-15T22:33:59Z","icon_url":"/icon/3.png","id":3,"name":"jason","updated_at":"2012-12-15T22:33:59Z"} */
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection" message:@"Connection Finished" delegate:self cancelButtonTitle:@"I know!" otherButtonTitles:nil];
    
    [alert show];
    
}

-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if ([response isKindOfClass:[NSHTTPURLResponse class]])
    {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
        NSLog(@"%d", [httpResponse statusCode]);
        //If you need the response, you can use it here
    }
}

Decode the image data in rails

Add this method into model- account.rb It will decode the image data into IOObject.

  def decode_icon_image_data
    # if the icon_image_data is set
    # decode it and handle by controller method
    
    if self.icon_image_data.present?
      data = StringIO.new(Base64.decode64(self.icon_image_data))
      data.class.class_eval {attr_accessor :original_filename, :content_type}
      data.original_filename = self.id.to_s+".png"
      data.content_type = "image/png"
    
      return data
    end
  end
In the controller we set up in the previous tutorial, we will check either the data from remote or from local. icon_io = @account.icon_image || @account.decode_icon_image_data So we don't have to change the controller.

Test your result

  • Open rail server with rails server
  • Choose the image in iphone, enter the name
  • Kick register button, you should be able to send the request
  • View the result in http://localhost:3000/accounts

Expect result and testing shell script

This result is expected, you will see a long JSON request parameter in terminal.



I have made a shell script for testing the server side, it hard code the JSON data used to register a member called jason with blue flower icon. You can download it from
Use it as sh curl_test.sh
Happy new year :)

2012年12月23日星期日

attr_accessor in Ruby

Introduction

Test attr_accessor though two simple programs

Example 1:

No instance variable declartion

class Car
 attr_accessor :band, :price
end

car = Car.new
puts "Band nil ? #{car.band.nil?}"  # => Band nil? true
puts "Price nil? #{car.price.nil?}" # => Price nil? true

Example 2:

Explicitly declare instance variable in method initalize

class Car
 attr_accessor :band, :price
 
 def initialize(args)
  @band = args[:option]
  @price = args[:price]
 end
end

car = Car.new(:option=>"Bentz", :price=>100000)
puts "Band nil ? #{car.band.nil?}"  # => Band nil? true
puts "Price nil? #{car.price.nil?}" # => Price nil? true

Summary and explantation

attr_accessor just created setter&getter method

it doesn't declare the instance variable for you, Util you declare the instance variable explicitly. In Example 1, if you tried to print out the two variable like car.band & car.price, you will actually get nothing returned