Archive | April, 2009

Top 10 Flex Programming Tips

There are some interesting tips I found during the time I work on Flex Programming. I will cover Embedding, Binding, Event Handling, Function Pointer, Mixin and more. I hope these tips will make your life easier when you work on Flex.


Tip 1: Embedding

Many Adobe Flex applications use external assets like images, sounds, and fonts. Although you can reference and load assets at run time, you often compile these assets into your applications. The process of compiling an asset into your application is called embedding the asset. Flex lets you embed image files, movie files, MP3 files, and TrueType fonts into your applications… When you embed an asset, you compile it into your application’s SWF file. The advantage of embedding an asset is that it is included in the SWF file, and can be accessed faster than when the application has to load it from a remote location at run time. The disadvantage of embedding an asset is that your SWF file is larger than if you load the asset at run time – Adobe

There are 3 ways to embed asset to Flex. In Flex code, you can use directive @Embed for direct use or you can associate the embedded asset with a variable by using the [Embed] metadata tag. In Style, you can use Embed to associate asset as well. Go check the syntax in detailed here.

Flex also have an option to embed any kind of file at compile time. The trick is with the ‘mimeType‘ option of the [Embedd] tag. while embedding other kind of files like text (or any) we need  to specify ‘application/octet-stream‘ for mimeType option. Here is the sample:

[Bindable]  
[Embed(source="MyFile.txt", mimeType="application/octet-stream")]  
private var myFileClass:Class;
...

var MyFileByteArray:ByteArrayAsset = ByteArrayAsset(new myFileClass());
var story:String = MyFileByteArray.readUTFBytes(MyFileByteArray.length); 

You must specify that the MIME type for the embedding is application/octet-stream, which causes the byte data to be embedded “as is”, with no interpretation. It also causes the autogenerated class to extend ByteArrayAsset rather than another asset class. For example, if you embed a PNG file without specifying this MIME type, the PNG data will be automatically transcoded into the bitmap format used by the player, and a subclass of BitmapAsset will be autogenerated to represent it. But if you specify the MIME type as application/octet-stream, then no transcoding will occur, the PNG data will be embedded as is, and the autogenerated class will extend ByteArrayAsset.

Tip 2: Binding

 

Leave a comment Continue Reading →

Powerful Extension of Flex DataGrid – Part 1

Features wanted!

To make Flex datagrid completed, I would like to have the following featues. AutoCompleted Search – Locate the data I want quickly if there are too many rows in my grid. Internationalization – Handle currency, number and date format. Data Export – Output the data in csv format, so users can import to Excel. Pagination - If I give the total number of records, the subset of the data rows and the number of rows per page, the grid should be able to do pagination and fire the events when user clicks on other pages. This article I will show you how to make these happen. :smile:

AutoCompleted Search

After you obtain the resultset from the database and pass it back to Flex as list of value objects, Flex, as usual, will convert it to ArrayCollection of value objects and bind it to the datagrid. If you want to filter out the record in the datagrid, you don’t need to remove the records from the ArrayCollection. All you need is to provide the implementation of the ArrayCollection’s filterFunction. Here is the example: 

...
[Bindable]
private var _data:ArrayCollection;

private function init():void
{
  _data = new ArrayCollection(
  [
  { "name":"One" },
  { "name":"Two" },
  { "name":"Three" },
  { "name":"Four" },
  { "name":"Five" }
  ]);

  _data.filterFunction = filterFunction;
}

private function filterFunction( item:Object ):Boolean
{
  var name:String = String( item.name ).toLowerCase();
  var searchStr:String = textInput.text.toLowerCase();
  return searchStr == name.substr( 0, searchStr.length );
}
//trigger when user type in search string in the text box
private function handleChange():void
{
  //this will iterate the dataset against the filterFunction
  _data.refresh();
}
...

Here is the caveat. When using a filterFunction in an ArrayCollection, the Flash Player will always search every item. It is not an effective way. To speed it up, Hillel Coren has documented an approach that the subsequent filters will search on the filtered list instead. His approach is elegant and well-documented. Go to his article for detailed. The demo is here. I found Hillel solution quite elegant. Apart from making the search more efficient, his design also modulizes the search code so that it can be unit tested easily.

The idea is to keep the last failed search string in each record. So, if the next search string begins with last search string, it is unnecessary to check each fields in the record before you can say it won’t be matched.


//---- SearchDemo.mxml ---
private function filterFunction( item:Person ):Boolean
{
  return SearchUtils.isMatch( item, textInput.text );
}

//--- SearchUtils.as ---
public static function isMatch( item:ISearchable, searchStr:String ):Boolean
{
  if (_enableFasterSearch && !quickCheck( item, searchStr )){
    return false;
  }
      
  var orSearchStrs:Array = searchStr.split( "," );
      
  for each (var orSearchPart:String in orSearchStrs)
  {
    var andSearchStrs:Array = orSearchPart.split( " " );
    var isMatch:Boolean;
        
    for each (var andSearchStr:String in andSearchStrs){
      isMatch = false;          
      for each (var field:String in item.getSearchFields()){
        if (item.matchesField( field, andSearchStr )){
          isMatch = true;
        }  
      }          
      if (!isMatch){break;}
    }  
        
    if (isMatch){
      item.setLastFailedSearchStr( "" );
      return true;
    }
  }      
  item.setLastFailedSearchStr( searchStr );
  return false;      
}
...

There are several things worth to mention here. The search routine is generic b/c it is against the item that implements the ISearchable Interface. The item implements this interface will provide the implementation of the matchesField method. So, the generic search routine can focus on providing features on top of it like ‘AND’, ‘OR’ filter and quick check algorithm.

NOTE: After you set the filterFunction, you will only get the filtered record if you iterate the ArrayCollection. If you want to get the full dataset, you need to do: 

for each (var obj:Object in arrayCollection.source)  
{  
     // do stuff  
} 

Again, thanks for Hillel’s tip.

I will talk about Data Export in Part 2 of this series.

Leave a comment Continue Reading →

Powerful Linux Text Processing Commands

Common Text Processing Commands

In our daily life, we deal with lots of data. The data normally is stored in text format for the ease of human to read. With the large amount of data we have, we need ways to deal with it. There are several things we frequently do on the data: Search, Filter, Sort and Analysis. In Linux, there are some powerful commands that I can use: cat, grep, find, sort, unique and etc. I found those commands quite powerful. So, I decide to put these down as my reference. This tutorial I will go over the basic text processing commands and how we use them together to achieve the tasks we often encounter in our workplace. 

cat

The power of “cat” is not just output a file to screen but to concatenates a list of file content and stream through the pipe to another program as input.

cat * | sort

find

The power of find is to list out the matched filenames based on metadata of the files like type, size, create date…

grep

“grep” helps you to list out the file(s) with the content that match the pattern(s) in regular expression. You can use it as content search across the files in your file system.

grep -H -R --color -n -P abc *

option:

  1. –color (highlight matching part in content with color)
  2. -n (show line number)
  3. -P PATTERN (perl regular expression pattern)
  4. -R (recursively)
  5. -l (only list out the filenames that match the pattern)
  6. -H show filename that matched.

cut

“cut” extracts sections from each line of input. (example of usage). Below the command will extract the 5th field and the rest from each line of file A using delimiter colon.

cut -d ":" -f 5- fileA

option:

  1. -c (character)
  2. -b (byte)
  3. -f 5- (field if the line can be broken down by delimiter)
  4. -d | (delimiter is pipe character)

sort 

The sort command sorts a file according to fields–the individual pieces of data on each line. By default, sort assumes that the fields are just words separated by blanks, but you can specify an alternative field delimiter if you want (such as commas or colons). Output from sort is printed to the screen, unless you redirect it to a file.

donor.data
Bay Ching 500000 China
Jack Arta 250000 Indonesia
Cruella Lumper 725000 Malaysia

Let’s take this sample donors file and sort it according to the donation amount. The following shows the command to sort the file on the second field (last name) and the output from the command:

sort +1 -2 donors.data
Jack Arta 250000 Indonesia
Bay Ching 500000 China
Cruella Lumper 725000 Malaysia

If the file is delimited by comma, you can use -t , to tell the sort the delimiter. You can use -u to output the uniqueness as well.


sort -t: +1 -2 company.data
Nasium, Jim:031762:Marketing
Jucacion, Ed:396082:Sales
Itorre, Jan:406378:Sales
Ancholie, Mel:636496:Research

To sort the file on the third field (department name) and suppress the duplicates, use this command:

sort -t: -u +2 company.data
Nasium, Jim:031762:Marketing
Ancholie, Mel:636496:Research
Itorre, Jan:406378:Sales

Note that the line for Ed Jucacion did not print, because he’s in Sales, and we asked the command (with the -u flag) to suppress lines that were the same in the sort field.

option:

  1. -f Make all lines uppercase before sorting (so “Bill” and “bill” are treated the same).
  2. -r Sort in reverse order (so “Z” starts the list instead of “A”).
  3. -n Sort a column in numerical order
  4. -tx Use x as the field delimiter (replace x with a comma or other character).
  5. -u Suppress all but one line in each set of lines with equal sort fields (so if you sort on a field containing last names, only one “Smith” will appear even if there are several).
  6. Specify the sort keys like this: +m Start at the first character of the m+1th field. -n End at the last character of the nth field (if -N omitted, assume the end of the line)

uniq

uniq – line level uniqueness. It prints the unique lines in a sorted file, retaining only one of a run of matching lines. Optionally, it can show only lines that appear exactly once, or lines that appear more than once. uniq requires sorted input since it compares only consecutive lines.

option:

  1. -u (print the unqiue lines only – lines only appear once)
  2. -d (print the duplicate lines only – lines appear more than once)
  3. -c (prefix each line with occurrence)

[code]]czoyMjY6XCJiYXNoJCBjYXQgdGVzdGZpbGU8YnIgLz4NClRoaXMgbGluZSBvY2N1cnMgb25seSBvbmNlLjxiciAvPg0KVGhpcyBsaW57WyYqJl19ZSBvY2N1cnMgdHdpY2UuPGJyIC8+DQpUaGlzIGxpbmUgb2NjdXJzIHR3aWNlLjxiciAvPg0KVGhpcyBsaW5lIG9jY3VycyB0aHJlZXtbJiomXX0gdGltZXMuPGJyIC8+DQpUaGlzIGxpbmUgb2NjdXJzIHRocmVlIHRpbWVzLjxiciAvPg0KVGhpcyBsaW5lIG9jY3VycyB0aHJlZSB0e1smKiZdfWltZXMuXCI7e1smKiZdfQ==[[/code]

[code]]czoxMzk6XCI8YnIgLz4NCmJhc2gkIHVuaXEgLWMgdGVzdGZpbGU8YnIgLz4NCjEgVGhpcyBsaW5lIG9jY3VycyBvbmx5IG9uY2UuPGJ7WyYqJl19ciAvPg0KMiBUaGlzIGxpbmUgb2NjdXJzIHR3aWNlLjxiciAvPg0KMyBUaGlzIGxpbmUgb2NjdXJzIHRocmVlIHRpbWVzLlwiO3tbJiomXX0=[[/code]

[code]]czoxNjA6XCI8YnIgLz4NCmJhc2gkIHNvcnQgdGVzdGZpbGUgfCB1bmlxIC1jIHwgc29ydCAtbnIgPGJyIC8+DQozIFRoaXMgbGluZSB7WyYqJl19b2NjdXJzIHRocmVlIHRpbWVzLjxiciAvPg0KMiBUaGlzIGxpbmUgb2NjdXJzIHR3aWNlLjxiciAvPg0KMSBUaGlzIGxpbmUgb2NjdXtbJiomXX1ycyBvbmx5IG9uY2UuICBcIjt7WyYqJl19[[/code]

wc

wc – word count. Apart from word count, it also does the following

  1. wc -w gives only the word count.
  2. wc -l gives only the line count.
  3. wc -c gives only the byte count.
  4. wc -m gives only the character count.
  5. wc -L gives only the length of the longest line.

tr

“tr” translate or delete characters. It is used for data cleaning job. Can we do pattern replacement?

tr ‘[:lower:]‘ ‘[:upper:]‘

The above command will convert all the lowest case to upper case.

tr ‘.’ ‘/’

The above will convert all the . character to /. And for translation, you cannot have -d option on. You may be asking when would we do that. Here is the common use case – convert window files to unix formatted file:

tr -d ‘\r’ < input_dos_file.txt > output_unix_file.txt

option:

  1. -s (squeeze the repeated characters into one character. eg. tr -s ‘\n’ )
  2. -d (delete characters eg. tr -d ‘\000′)

sed

“tr” can do character replacement. But if you want to do pattern replacement, you need to use sed. usage: sed -e s/pattern/replacement/flags

sed -e s/one/another

sed -e s/[aeiou]/_/g

 Note the use of the “g” flag so that you apply the pattern/replacement to every match instead of just the first one.

awk

  

Put them all together

[code]]czo4NjpcImNhdCAqIHxncmVwIGx1Y2VuZS1jb3JlfGN1dCAtZjIgLWRcJyBcJ3x1bmlxfHRyIFwnLlwnIFwnL1wnfCBhd2sgXCd7cHJpbnRmIFwiJXtbJiomXX1zLmNsYXNzXFxuXCIsICQxfVwnXCI7e1smKiZdfQ==[[/code]

Leave a comment Continue Reading →