Wednesday, March 25, 2015

jQuery Change Image src with Fade Effect

I think instead of using FadeIn and fadeOut, its better to use fadeTo functionality as fadeIn and fadeOut created a time gap between them for few micro-seconds.

I have used above code from Sylvain : thanks to him

Use fadeTo():

$("#link").click(function() {

  $("#image").fadeTo(1000,0.30, function() {
      $("#image").attr("src",$("#link").attr("href"));
  }).fadeTo(500,1);
  return false;
});

Use fadeIn and fadeOut:

$(".thumbs a").click(function(e) {
    e.preventDefault();
    $imgURL = $(this).attr("href");
    $(".boat_listing .mainGallery")
        .fadeOut(400, function() {
            $(".boat_listing .mainGallery").attr('src',$imgURL);
        })
        .fadeIn(400);
});

自動配色的線上工具,快速產生合適的色票

Coolors 是一個免費的自動配色工具,可以讓您在線上快速產生各種適宜的色票,省去自己配色的煩惱。

http://coolors.co/

Monday, March 23, 2015

Pass a object by value - assigning / copying object

JSON method:

var myObjDefault = JSON.stringify({
  price: {min: 0, max: 999},
  weight: {min: 0, max: 999},
});

var myObj = JSON.parse(myObjDefault);

Jquery Method:

// Shaw Copy
var oShallowCopy = jQuery.extend({}, o);

// Deep Copy
var oDeepCopy    = jQuery.extend(true, {}, o); 

Reference:

http://stackoverflow.com/questions/7574054/javascript-how-to-pass-object-by-value

Sunday, March 22, 2015

Magento programatically refresh reindexing indexes

I have written a script to update the product description information programatically. However, after I run the script, the URL is reset to a empty blank value. Refresh the indexes will re-generate the URL keys.

<?php
### Magento programatically refresh reindexing indexes

function refreshAllIndexes() {
  /* @var $indexCollection Mage_Index_Model_Resource_Process_Collection */
  $indexCollection = Mage::getModel('index/process')->getCollection();

  foreach ($indexCollection as $index) {
    /* @var $index Mage_Index_Model_Process */
    $index->reindexAll();

    #echo '<pre>' . print_r($index->debug(), TRUE) . '</pre>';
  }
}

/**
 * catalog_product_attribute     Product Attributes
 * catalog_product_price         Product Prices
 * catalog_url                   Catalog URL Rewrites
 * catalog_product_flat          Product Flat Data
 * catalog_category_flat         Category Flat Data
 * catalog_category_product      Category Products
 * catalogsearch_fulltext        Catalog Search Index
 * cataloginventory_stock        Stock Status
 * tag_summary                   Tag Aggregation Data
 * targetrule                    Target Rules
 */
function refreshIndex($indexName) {
  $process = Mage::getModel('index/indexer')->getProcessByCode($indexName);
  $process->reindexAll();
}
?>

Reference:

http://www.kennydeckers.com/magento-programatically-reindexing-indexes/

Tuesday, March 17, 2015

Get Product Information Query

Attribute Code SQL Equivalent Example
eq = $collections->addAttributeToFilter('price', array('eq' => 10.00));
neq != $collections->addAttributeToFilter('price', array('neq' => 10.00));
like LIKE $collections->addAttributeToFilter('name', array('like' => '%VJTemplates%'));
nlike NOT LIKE $collections->addAttributeToFilter('name', array('nlike' => '%VJTemplates%'));
in IN () $collections->addAttributeToFilter('id', array('in' => array(1,2,3,4)));
nin NOT IN () $collections->addAttributeToFilter('id', array('nin' => array(1,2,3,4)));
is IS
notnull IS NOT NULL
$collections->addAttributeToFilter('description', 'notnull');
null IS NULL $collections->addAttributeToFilter('description', 'null');
moreq >= $collections->addAttributeToFilter('price', array('moreq' => 10.00));
gt > $collections->addAttributeToFilter('price', array('gt' => 10.00));
lt < $collections->addAttributeToFilter('price', array('lt' => 10.00));
gteq >= $collections->addAttributeToFilter('price', array('gteq' => 10.00));
lteq <= $collections->addAttributeToFilter('price', array('lteq' => 10.00));
finset FIND_IN_SET() $collections->addAttributeToFilter('custom', array('finset' => '1'));
from >= $collection->addAttributeToFilter('created_at', array(
'from' => '10 July 2013',
'to' => '11 July 2013',
to <= 'date' => true
date ));
datetime $collection->addAttributeToFilter('created_at', array(
'from' => '2013-01-01 00:00:00',
'to' => '2013-12-31 00:00:00',
'datetime' => true
));

Get a list of attributes of a product:

$attributes = Mage::getSingleton('catalog/config')->getProductAttributes();
echo '<pre>' . print_r($attributes, TRUE) . '</pre>';

AND Operation:

$collections = Mage::getModel('catalog/product')
       ->getCollection()
       ->addAttributeToSelect(array('id', 'sku', 'name', 'price'))
       ->addAttributeToFilter('name', array('eq' => 'test car'))
       ->addAttributeToFilter('price', array('eq' => 10.00))
       ->load();

OR Operation:

$collections = Mage::getModel('catalog/product')
       ->getCollection()
       ->addAttributeToSelect(array('id', 'sku', 'name', 'price'))
       ->addAttributeToFilter(
         array(
           array('attribute' => 'name', 'eq' => 'test car'),
           array('attribute' => 'sku', 'regexp' => '^ABC'),
         )
        )
       ->load();

Looping through the collection:

foreach ($collection as $prodObj) {
  echo $prodObj->getId() . ' ';
  echo $prodObj->getSku() . ' ';
  echo $prodObj->getName() . ' ';
  echo $prodObj->getPrice() . ' ';
}

Reference:

http://www.vjtemplates.com/blog/magento/addattributetoselect-addattributetofilter-addfieldtofilter

Monday, March 16, 2015

To redirect to a page from a template in Magento


Mage::app()->getResponse()->setRedirect(Mage::getBaseUrl());

Wednesday, March 11, 2015

Set JQuery UI modal dialog overlay background color

To remove the strip and use a custom background color you can do like this on the open event :

open : function(event, ui){
    $("body").css({
        overflow: 'hidden'
    });
    $(".ui-widget-overlay").css({
        background:"rgb(0, 0, 0)",
        opacity: ".50 !important",
        filter: "Alpha(Opacity=50)",
    });
},
beforeClose: function(event, ui) {
    $("body").css({ overflow: 'inherit' })
}

Reference:

http://stackoverflow.com/questions/5583995/set-jquery-ui-modal-dialog-overlay-background-color

CSS Sprites - offset the background

Method 1 (preferred):

<html>
<head>
<style>
.myul {
  position: relative;
}

.myli {
  position: absolute;
  list-style: none;
  width: 52px;
  height: 52px;
  background: url('mysprite2.gif') no-repeat;
  display: block;
  top: 0px;
}

.myli:hover {
  background-position-y: -51px;
}

#myli1 {
  background-position-x: 0px;
  left: 0px;
}

#myli2 {
  background-position-x: -51px;
  left: 54px;
}

#myli3 {
  background-position-x: -102px;
  left: 108px;
}

#myli4 {
  background-position-x: -153px;
  left: 162px;
}
</style>
</head>
<body>

<ul class="myul">
  <li id="myli1" class="myli"></li>
  <li id="myli2" class="myli"></li>
  <li id="myli3" class="myli"></li>
  <li id="myli4" class="myli"></li>
</ul>

</body>
</html>

Method 2:

<html>
<head>
<style>
.myul {
  position: relative;
  width: 400px;
  height: 200px;
  background: transparent url('mysprite.jpg') no-repeat;
  padding: 0px;
}

.myli {
  position: absolute;
  list-style: none;
  width: 100px;
  height: 200px;
  top: 0px;
  display: block;
}

#myli1 {
  left: 0px;
}

#myli2 {
  left: 100px;
}

#myli3 {
  left: 200px;
}

#myli4 {
  left: 300px;
}

#myli1:hover {
  background: transparent url('mysprite.jpg') 0px -200px no-repeat;
  opacity: 0.8;
}

#myli2:hover {
  background: transparent url('mysprite.jpg') -100px -200px no-repeat;
  opacity: 0.8;
}

#myli3:hover {
  background: transparent url('mysprite.jpg') -200px -200px no-repeat;
  opacity: 0.8;
}

#myli4:hover {
  background: transparent url('mysprite.jpg') -200px -200px no-repeat;
  opacity: 0.8;
}

</style>
</head>
<body>

<ul class="myul">
  <li id="myli1" class="myli"></li>
  <li id="myli2" class="myli"></li>
  <li id="myli3" class="myli"></li>
  <li id="myli4" class="myli"></li>
</ul>

<img src="mysprite.jpg" />

</body>
</html>

hide the title bar and close button in jQuery UI

$j("#myDiv").dialog({
  create: function(event, ui) {
    $j('.ui-dialog-titlebar').hide(); // hide the title bar.
    $j('.ui-dialog-titlebar-close').hide(); // hide the close button.
  },
});

css complex attribute selector

/* Attribute Present Selector */
#checkoutSteps a[target] {
  color: #fff;
}

/* Attribute Equals Selector */
#checkoutSteps label[for="billing:firstname"] {
  color: #fff;
}


/* Attribute Begins With Selector */
#checkoutSteps label[for^="billing:"] {
  color: #fff;
}

/* Attribute Contains Selector */
#checkoutSteps label[for*="billing:"] {
  color: #fff;
}


/* Attribute Ends With Selector */
#checkoutSteps a[href$=".pdf"] {
  color: #fff;
}

/* Attribute Spaced Selector - attribute is within space separated list */

a[rel~="tag"] {...}

<a href="#" rel="tag nofollow">...</a>

/* Attribute Hyphenated Selector - attribute is within dash separated list */

a[lang|="en"] {...}

<a href="#" lang="en-US">...</a>

Reference:

http://learn.shayhowe.com/advanced-html-css/complex-selectors/

Tuesday, March 10, 2015

How can I restrict IP addresses in .htaccess with the reverse proxy in front?

Since requests to your site are usually first handled by the Varnish reverse proxy, you can't use the sender IP address to block certain IP addresses in your .htaccess configuration file. The following will not work because all requests the web server receives will originate from the proxy address, and in consequence, no access will ever be allowed:

Order deny,allow
Deny from All

Allow from 1.2.3.4
Allow from 2.3.4.5

There is a way of checking the real sender address, though, because Varnish puts it in the HTTP header X-Forwarded-For.

A few additional lines make Apache check this HTTP header, too:

Order deny,allow
Deny from All

SetEnvIF X-Forwarded-For "1.2.3.4" AllowIP
SetEnvIF X-Forwarded-For "2.3.4.5" AllowIP

Allow from env=AllowIP
Allow from 1.2.3.4
Allow from 2.3.4.5

This ruleset will work both for requests handled by Varnish (Port 80) and directly handled by Apache (Port 81).

https://freistil.zendesk.com/entries/21852711-How-can-I-restrict-IP-addresses-in-htaccess-with-the-reverse-proxy-in-front-

Check the bash shell script is being run by root or not

#!/bin/sh

# Make sure only root can run this script
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

To ignore files in subversion

To ignore files in subversion:

# svn propedit svn:ignore /www/magento1.9.1/media/catalog/product

cache

To remove svn:ignore property:

// For current directory

# svn propdel svn:ignore .

// For recursive

# svn prodel svn:ignore -R

Failed opening 'SoapClient.php' for inclusion

2015-03-10T17:43:18+00:00 ERR (3): Warning: include(): Failed opening 'SoapClient.php' for inclusion (include_path='/var/www/html/magento1.9.1/app/code/local:/var/www/html/magento1.9.1/app/code/community:/var/www/html/magento1.9.1/app/code/core:/var/www/html/magento1.9.1/lib:.:/usr/share/pear:/usr/share/php')  in /var/www/html/magento1.9.1/lib/Varien/Autoload.php on line 94

Double check if Soap is installed:

# yum list installed | grep php-soap

php-soap.x86_64                       5.4.16-23.el7_0.3                @updates

Install php-soap:

# yum install php-soap

Make sure the components have the same versions:

# yum list installed | grep php

Update PHP:

# yum update php

Make sure SOAP is loaded:

# systemctl restart httpd
# systemctl restart php-fpm
# php -m | grep soap

Monday, March 9, 2015

the download attribute on a link

when the user clicks the link, the download attribute appears in the save dialog instead of the garbled mess that was there before. In this case, the file will be downloaded as expenses.pdf. The download attribute also triggers a force download.

<!-- will download as "test.pdf" -->
<a href="/files/test.pdf" download="test.pdf">Download test.pdf</a>

Reference:

http://davidwalsh.name/download-attribute

Saturday, March 7, 2015

Announcing .NET Native Preview

We’re thrilled to announce the first release of .NET Native. Windows Store apps start up to 60% faster with .NET Native and have a much smaller memory footprint. Our first release is a Developer Preview that allows you to develop and test apps with this new compiler. This preview release of .NET Native offers you the performance of C++ with the productivity of C#. .NET Native enables the best of both worlds!

Reference:

http://blogs.msdn.com/b/dotnet/archive/2014/04/02/announcing-net-native-preview.aspx

阿米近視眼睛保養預防的方法---眼睛運動、按摩、飲食

你如何對待你的眼睛?目不轉睛打電腦、看書、看報、看電視,身體好不容易得空休息喝杯茶,眼睛還在骨碌碌打轉,繼續為工作奮戰。
這還不包括因壓力過大造成的失眠、熬夜等,眼睛可以真正休息的睡眠時間,被切割得片段而零碎。
眼睛的使用時間無限延長,眼睛肌肉持續緊張狀態下,加上具滋潤作用的淚液,因過度使用而減少分泌,導致眼睛疲憊乾澀甚至疼痛。
怎麼對待眼睛,它就怎麼回饋你。眼睛這個「超時工作」的重度勞動者,偶爾也會提出抗議。
根據美國國家職業衛生安全局報告,一天在電腦前工作3小時或以上,88%的人會有眼睛疲勞的情形。伴隨而來肩頸痠痛、頭疼,更成為多數人生活中的困擾。
以中醫而言,眼睛是五臟六腑的鏡子,反應人的生命活力和身體狀況。
「很多疾病表現都可從眼睛得知,」林口長庚醫院中醫部醫師陳俊良指出。
比如外眼角如果有血絲或眼屎出現,反映心血管和大腦功能,可以推測是因為失眠的緣故。
黑色的瞳仁部份代表最重要的肝腎功能,也是病症是否可以醫治好轉的關鍵,通常瞳仁散漫無神,代表病症已經傷害肝腎,沉痾已深,元氣將盡。
「身體好,眼神自然有凝聚之氣,這是所謂的氣聚神凝,」有著一雙明亮大眼,學習氣功十年,梅門一氣流行的太極教練饒懷英解釋。
但,怎麼做才能養出一雙目測千里的明眸?

第1招:勤練眼睛運動

眼睛肌肉疲憊,多半是長時間過度專注於近距離上,缺乏看遠的訓練和運動。許多眼科醫師認為,這也是導致孩童近視的主因。
眼睛是五臟六腑的氣機,氣功大師李鳳山提到,要養氣,先從眼睛鍛鍊起。
他每日必練的「定神」功法,是利用凝視遠山和數近距離的紗窗格子,來訓練眼睛做遠近距離的運動。
上班族可以在辦公室中找一個最遠的焦距,凝神注視30秒左右做練習,也可以達到效果。
容易分心的小朋友,可以利用自己的食指緩緩拉遠拉近約1分鐘做定神訓練,饒懷英建議。
平日多讓眼睛上下左右慢慢轉動,可以帶動眼睛韌帶肌肉活動,消除眼睛疲勞。
此外,眼要常閉,不僅可以增加淚液的分泌,也可以達到「閉目養神」的功效。
中醫認為眼睛使用過度時,容易產生肩頸痠痛,口乾舌燥、緊張焦慮等虛症,「根本方式是讓眼睛歇息,」陳俊良醫師指出,其實適當休息後,這些症狀都可以得到改善。
在美國行之有年的「20/20護眼定律」頗值得參考:每看書或電腦20分鐘後,注視6公尺遠的地方20秒,便可維護視力健康
動作指導示範:梅門一氣流行養生學苑太極教練饒懷英

後顧無憂法:
1.坐定,兩手放在大腿上,全身放鬆
2.吸氣,脖子向左邊慢慢轉緊,眼睛儘量往後方看。
3.慢慢吐氣,脖子轉回中央。
4.換成右邊再做一次。

第2招:迅速消除疲勞的養眼穴道按摩

按摩可以增加眼睛的血液循環。眼睛痠澀時可按壓下述穴道,直到感覺痠脹即可。
纘竹穴:眉毛內側
睛明穴:眼睛內側
承泣穴:眼睛下緣落淚處
太陽穴:額頭兩側
合谷穴:手掌虎口處中心點

註:眼壓高、青光眼、高血壓者或眼睛有紅腫熱痛時,不要按摩。
註:一般眼睛的急性發炎期,如紅腫熱痛時,可以暫時以冰敷緩解;
但如果一般保健,則以熱敷為宜。疾病若未改善,請就醫診治。

資料提供:林口長庚醫院中醫部

 其實看書看電視看電腦一段時間後要休息相信是大家都知道的事,但是要做到真的很難,因為總是會忘了時間,要不然就是看得太入迷以至於不想起來。米不鹹在這裡分享一個對我很有用的方法:用手機定時。我現在坐下來讀書或用電腦前都會先設定45分鐘,接著就可以專心做我的事情,不用擔心要一直注意時間。45分鐘一到我就再定時5分鐘,接著站起來甩甩手伸展一下身體,做做眼睛運動或按摩,喝點水。屢試不爽。

第3招:茶飲顧眼

中醫認為肝開竅於目,日常的茶飲調養,可緩解眼睛的疲憊不適。像菊花、枸杞、決明子等都是中醫的養眼茶飲。
鑽研中藥理論多年,致力於養生與美味兼俱的藥膳美食家林秋香,每逢夏季必定親自熬煮大人小孩皆宜的桂圓枸菊茶,當做茶飲(菊花5錢、枸杞2兩,桂圓或紅棗10粒,以2000cc的水煮15分鐘後,濾淨渣滓)。她認為對於健忘、容易受到驚嚇、心血不足的人很有幫助。
至於口肝舌燥,一般稱「火氣較大」的人,林秋香建議可以在枸菊茶煮好後,加入約300cc的甘蔗汁,有清涼退火的功效。

 這個對生活忙碌的人來說是還挺麻煩的,周末有空喝喝就好。

第4招:使你眼睛明亮的簡單動作

熨目明神法:眼睛疲勞時隨時可練習。
1.手心摩擦溫熱
2.將掌心平貼眼部,慢慢吐氣,來回數次。
枸杞、女真子等具補肺脾功效,也可當做一般保健茶飲。但是一般容易臉紅、暴怒、胸悶及高血壓人的不適合飲用。
陳俊良中醫師建議,可改用清熱肝火的決明子、青葙子、密蒙花(可在中藥店購得)泡水飲用,如面紅耳赤情形未改善,最好就醫診治。

第5招:蔬菜水果,吃出好眼力

存在於蔬菜水果中的維生素A、B群和抗氧化物,正是打造好眼力不可或缺的營養素。
富含維生素A的食物:莧菜、金針花、雪裡紅、蕃薯葉、枸杞、九層塔、木瓜、芒果、綠茶
維生素A可以提供視網膜所需的營養。如果將視網膜比喻成相機底片,維生素A則是底片上的感光材料,負責吸收藍光,防止視網膜的敏感區域受到光線傷害。一般乾眼症也是缺乏維生素A所致。
閱讀、使用電腦等會耗損大量維生素A,因此,平時應該多攝取含β-胡蘿蔔素的食物,如魚肝油、蕃薯、胡蘿蔔、肝臟、南瓜、深綠色蔬菜等,「因為β胡蘿蔔素,會在體內轉換成為維生素A,」台北醫學大學附設醫院營養部主任楊淑惠解釋。
她特別提醒,維生素A屬於脂溶性維生素,意即在有油脂的情況下,吸收情形最好。
因此像胡蘿蔔汁等,最好在飯後服食用;或是在燙青菜中拌點橄欖油,可以幫助維生素A的吸收。
富含維生素B群的食物:糙米、胚芽米、全穀類食物、乾燥酵母、豆類、牛奶、綠葉蔬菜
與身體蛋白質熱量代謝有關的維生素B群,可維持視神經及角膜的健康。
壓力及油炸、油脂食物,均會造成維生素B群的耗損,造成眼睛畏光流淚、視力模糊等症狀,尤其是糖尿病及青光眼病人,容易造成視神經的萎縮及視網膜病變,維生素B群的補充更為重要。
含豐富抗氧化物的食物:青椒、青花菜、甜椒、菠菜、蕃薯、蕃茄及各類水果。
其他抗氧化物質如維生素C、類胡蘿蔔素等,則可防治紫外線產生的自由基對眼睛造成的傷害,比如引起白內障和黃斑性病變,甚至失明。
美國新近研究發現,紅色、黃色、橘色的蔬果,如玉米、橘色甜椒,紅葡萄、奇異果等,含有抗氧化物黃色素(Lutein)和玉米黃質(Zeaxanthin),可以延緩並預防與老化相關的視力衰退。
美國哈佛大學研究指出,多吃富含類胡蘿蔔素蔬果(如青花菜、菠菜)的人,視網膜衰退程度較輕微。
專家建議,一日攝取5種以上不同種類的蔬果,才能維持眼睛所需營養。
維生素之間是相互輔助的,只有飲食均衡,才能發揮最大效益,」楊淑惠提到,身體本身營養素俱足,才能幫助維生素A等達到更好的吸收與補充。
茹素多年的饒懷英有個簡單方法,她以青、紅、黃、白、黑的五色食物為原則,每天儘量攝取不同種類的食物,達到均衡飲食。
至於是否需要額外補充維生素補充劑,楊淑惠認為,天然食物就是最佳的補充品,飲食多樣化就毋須擔心維生素不足。
例如小蕃茄便是楊淑惠的天然綜合維他命。打電腦、看書,隨手一抓,吃起來簡單方便,富含維生素、抗氧化物、解渴止飢,又不發胖,她認為這是上班族最好的補充品。
此外,儘量選擇當季本地產的水果,價格便宜,營養更多,因為研究發現,維生素C在運送過程中,容易大量流失。
不論觀賞令人摒息的畢卡索名畫或大自然天光雲影的瞬息萬變,要將花花世界收進眼底,還得先要有一副好眼睛。
筋骨鞏固,心胸開放,眼睛自然清澈明亮。

Reference:

http://happynano0420.pixnet.net/blog/post/37501028-%E9%98%BF%E7%B1%B3%E8%BF%91%E8%A6%96%E7%9C%BC%E7%9D%9B%E4%BF%9D%E9%A4%8A%E9%A0%90%E9%98%B2%E7%9A%84%E6%96%B9%E6%B3%95---%E7%9C%BC%E7%9D%9B%E9%81%8B%E5%8B%95%E3%80%81%E6%8C%89

我學 Machine Learning 的方法

有人問我這個問題,想說就寫在這吧。目前還學不到家,只有斷斷續續讀個一陣子,有錯還請大家指正。

讀 Data mining 的書

一開始我讀 data mining 之類的課本、講義,發現內容講得滿概念的。但若只是想拿 ML 來用,那看這類文件會比較容易上手。比方 Introduction to Data Mining 寫得挺不錯的,可謂深入淺出!官網附的投影片挺棒的,可以先「快速」 (相對於看書來說……) 看一遍,再挑有興趣的部份閱讀課本。若有耐性慢慢讀完課本,會較有系統性地認識相關內容。由於碩論做 clustering 的緣故,我有好好地讀書本 clustering 部份。不過 clustering 論文種類多到爆炸,看完這本的內容也只是苦痛的開始而已……。

讀國外大學的授課講義

若想進一步了解 model 的原理,那就需要讀 ML 課程用的課本和講義。這類文件滿多的,其中我強力推薦 Andrew Ng 教的 Stanford CS229 Machine Learning。大部份教材在講解 model 最關鍵的數學時,只會從天空掉下來一句「套用 gradient ascending 求最大值」、「運用 EM 求最佳值」之類的話,接著結果就神奇地飛出來。這份講義卻從最基礎的數學開始講,包含需要用到的微分、線性代數、機率等,讓讀者有能力自己從頭推導數學算式,算是 ML 文件裡最親切的教材。當然,讀者也要有興趣慢慢地啃才行。我大概啃了一半多一點內容,收獲良多。可惜久一沒用也只記得概念了。有機會想再從頭自己推導一次。我覺得 Andrew Ng 數學寫得相當漂亮,這是我第一次察覺寫數學式和寫程式一樣,也有美醜、易懂難懂之分。附帶一提,當初會看這份教材是看 Mr. Saturday 推薦才讀的,感謝 Mr. Saturday 推薦。
後來我陸續看了一些不同國外大學的 ML 課程講義,發覺大家的切入點差很多,各有不同考量。像 MIT OCR 6.867 Machine Learning 有教 HMM,Stanford CS229 沒教。A Fundamentalist Organization of Machine Learning 提到由 Learning theory 的方式切入 ML,而不要走馬看花講一堆 model (作者稱為 “zoo approach”,挺傳神的譬喻)。我只有從 Andrew Ng 的講義裡讀了一點 learning theory,懂些基本觀念 (bias 和 variance),感覺挺有用的。若對 learning to theory 有興趣,印象中該文作者有推薦 15-859(B) Machine Learning Theory,Spring 2009。我看了一晚講義,內容是從簡單的假設環境中推導出明確的性質,還挺有趣的。但看到後來就看不懂了,也不明白能做什麼,就沒繼續看了。

讀 Wikipedia

此外,我發覺 Wikipedia 是學東西的好地方。有代表性的方法早已有系統地記錄下來,又提供詳細的參考資料可以一路讀下去。比方說想學 Linear classifier ,比起查書,查 Wikipedia 更有效率。我常拿 Wikipedia 內容和其它文件交叉對照,弄明白看不懂的部份。讀這些東西需要的是耐心以及不傷眼的 Wikipedia CSS 樣版

讀經典課本

後來又看到 Mr. Saturday 提到 Elements of Statistical Learning: data mining,inference,and prediction. 2nd Edition.,而且官網還有附完整電子書,就載來看看。不得不說這本書數學超硬,但內容超級紮實,相當值得一讀。我挑有興趣且讀得下去的部份加減看,學到 bagging、random forest 等東西,讓我擴展眼界,明白許多原理。除數學太硬之外,這本書另一問題是實驗資料太小了,令人懷疑實驗結果是否適用於真實世界的情況。只好先暫時相信大師,之後再從實驗中確認。
有興趣的話可以在 Amazon 查一下其它書,或以這本書為底看相關書籍。ML 有不少經典書籍,也有針對影像處理或文字處理的。

其它

O’Reilly 出的 Programming Collective Intelligence - O’Reilly Media 也是不錯的書,適合初學者閱讀。配合使用情境,作者簡單地解釋 model 的概念並用 Python 說明如何實作。最令人讚賞的是,作者還有比較各個模型的優缺點。雖然分析的內容不見得正確,對初學者來說挺受用的。

總結

讀這些理論時,我發覺有許多文件提供不同的講解方式,可以多比較一番,找自己看得懂的。不用刻意從某個地方學會某種 model。文中提的是我學習的歷程,每個人的需求不同,數學底也不同,我的經驗不見得適用於其他人。寫在這裡供大家做個參考,有錯還請告知,感謝。

Reference:

http://fcamel-fc.blogspot.ca/2010/03/machine-learning.html

學習和開發 Python 的好幫手

慣用 IDE 的人會推 Eclipse + PyDev, 網路上有不少教學文章。我則是慣用 VIM IPython

這裡有我針對 Python 設的 vim 設定檔, 有興趣用的人可以撿需要的部份用, 或是直接複制整個 .vim 和 .vimrc 也行 (若你原本沒設 .vim 和 .vimrc):

$ git clone git://github.com/fcamel/configs.git
$ cp -r configs/.vim ~
$ cp configs/.vimrc ~

推薦讀 IPython Tip Sheet 學習使用 IPython, 花個十分鐘將可獲得兩倍以上的學習速度。我常最用的指令是 ? 和 ??, 分別會秀出物件 (函式) 說明和原始碼。它的運作原理很簡單, 因為在 Python 的世界裡, 所有東西都是物件, 而物件的 __doc__ 欄位存有文件, __file__ 欄位則存有載入的檔案路徑。因此 IPython 可以輕易地讀入文件和原始碼。

如此一來, 在 screen 裡開兩個 terminal, 一個開 IPython; 一個開 VIM。想試什麼簡單程式就在 IPython 裡試, 有疑問就用 ? 和 ?? 查。在 VIM 裡可按 F10 執行內容, 方便試較長一些的程式。實際開發時則在 VIM 裡切兩個視窗, 一個寫 unit test, 一個寫 software-under-test。在 unit test 的視窗裡按 F10 執行程式, 有錯就切到 software-under-test 的視窗改。若有錯不知錯在那想了解物件內容, 則在 unit test 裡呼叫 IPython [1], 進入 IPython 內了解詳情, 寫起來很有效率。



Reference:

http://fcamel-life.blogspot.ca/2010/03/python.html

學 Python 的入門書

常看到有人問這問題,想說來寫篇心得,省得重覆回一樣的問題。
我在學 Python 前已學過別的程式語言,所以想找針對已學過程式的人的書。一開始翻許多人推薦的《Learning Python》,發現它是針對沒學過程式的人,有太多篇幅在介紹基本觀念 (如 if 是什麼 ),翻沒幾頁就沒耐性看下去。而《Programming Python》又太厚了,於是找別本書。
後來 Scott 推薦我看《Python Essential Reference》 (目前出到第四版,包含 Python 2.6 的新功能),我一看就驚為天人,「if、elif、else」只有一頁!內容包含完整語法,以及特殊情況 ( 若 if 之後想放空的 statement ,要用 pass )。沒錯,這就是我要的書,去蕪存菁地讓讀者立即掌握 Python 的語法。附帶一提,Scott 明明已學會了,竟然還買了一本用來傳教,真是面惡心善的好學長。
看完這本後,有時查些 Python 觀念或函式名稱,發現常連到《Dive into Python》,才發覺這本也滿有名的,而且還有完整免費的網頁版。於是又找時間看了《Dive into Python 3》,順便了解 Python 3 有啥有趣的東西。發覺這本書超合我胃口,直接用完整的例子說明語法,在學到語法的同時,也明白怎麼實際使用這些語法。有些書就像辭典一般,提了很正式的語法,讀起來很累,讀完卻不知能怎麼用它們。《Dive into Python 3》不但用生動的實例避免這個問題,並進一步深入淺出地介紹運作細節。而且還提到如重構、單元測試等寫軟體的重要觀念,又有詳細的 Python 2 和 3 的比較。若只對 Python 2 有興趣也沒關係,大部份語法仍適用於 Python 2.6 (2.6 是承接 Python 2 和 3 的橋樑)。
總結來說,若你沒學過程式語言,我不知道能推薦什麼書藉。或許可以參考《Python Programming: An Introduction to Computer Science》,這是 MIT 6.00: Introduction to Computer Science and Programming 的參考書,該課程用 Python 教沒寫過程式的學生學會電腦科學家的思考方式。若有學過程式語言,《Python Essential Reference》或《Dive into Python 3》都值得一看。除了學會 Python 之外,兩者提供不同的額外內容,都看也不會浪費時間。

延伸閱讀

學會 Python 基本語法後,可以先看這幾篇了解如何寫出更道地的 Python。道地的 Python 程式不但易讀、易維護,通常也表示更有效率:
再來,可以到《Python Essential Reference》作者 David Beazley 的網站挖寶,像是:
另外若對 design patterns 有興趣,可以看 Google 員工 Joe Gregorio 寫的(The Lack of) Design Patterns in Python
《Python Cookbook》也有不少經典寫法,不過該書有點舊了 (到 Python 2.4),有些方法已用不到,看的時候要挑一下。
原以為延伸閱讀應該沒多少東西,沒想到我拉拉雜雜也看了不少文件,整理到後來就累了。不知何時 Python 才會像 Java 有本《Effective Python》,一本搞定大部份的注意事項和經典寫法。

備註:設定開發環境


Reference:

http://fcamel-fc.blogspot.ca/2010/02/python.html

Python 的特別之處 (1)

從新手的眼中來看 Python,比較能看出 Python 和其它語言不同之處。最近有機會幫別人快速上手 Python,就順便整理一下我從中發覺 Python 較為突出的優點。

list、dictionary and string

平時 coding 最常用到的 container 就是 list 和 dictionary,另外也會常用到字串操作,Python 提供方便的方法來操作它們。string 可看成一個有實作 list 介面的類別,一些常用操作像是 slice:"abcd"[1:3] 回傳 "bc";負數的索引: "abcd"[-1] 回傳 "d";直接和 for-loop 整合在一起:
In [1]: for ch in "abcd":
  ....:         print ch
  ....:
a
b
c
d
讓存取這些常用資料型態輕鬆許多。

iterator

使用 iterator 比傳統的 for (i=0; i 來得清楚,Python 針對 iterator 下了不少工夫,提供好用的輔助函式,像是 enumerate 補足需要用到 index 的情況:
In [2]: for i, n in enumerate([1, 3, 5]):
  ....:     print i, n
  ....:
0 1
1 3
2 5
使用 zip 整合多個 list:
In [3]: names = ["John", "Marry", "Tom"]
In [4]: sexes = ["Male", "Female", "Male"]
In [5]: for name, sex in zip(names, sexes):
  ....:     print name, sex
  ....:
John Male
Marry Female
Tom Male

map, filter and reduce

任何使用過 map 的人,都會喜歡 map 輕巧的用法,來看幾個例子:
In [1]: map(int, ["12", "37", "999"])
Out[1]: [12, 37, 999]
In [2]: map(str, [12, 37, 999])
Out[2]: ['12', '37', '999']
int 是一個函式,將傳入的物件轉成整數;str 則是轉成字串。使用 map 可以將一個 iterator 轉為另一種 list。
另一個常見的情境是,從一個 list 裡篩選出需要的物件,比方說只留下偶數:
In [1]: numbers = [1, 2, 3, 4, 5]
In [2]: filter(lambda x: x % 2 == 0, numbers)
Out[2]: [2, 4]
或像 filter(lambda s: s.endswith('.py'), file_names) 只留下結尾為 ".py" 的字串。
除 map 和 filter 的重心放在轉換 list 之外,reduce 則是將 list 匯整成一個物件。有了這些函式,就能任意的操作 list,用以匯整或擴散資料容器。
比方說將一串數字加起來:
In [1]: numbers = [1, 2, 3, 4, 5]
In [2]: reduce(lambda x, y: x + y, numbers, 0)
Out[2]: 15
上面這個例子可以用內建的 sum 取代,來看另一個複雜點的例子,將一串 0、1 值合成一個整數:
In [1]: bits = [0, 1, 0, 0, 1]  # bits[i] 的值表示 2^i 的系數

In [2]: reduce(lambda x, (i, b): x | (b << i), enumerate(bits), 0)
Out[2]: 18

list comprehension

map 和 filter 雖然方便,要用到 lambda 或是混合使用時就沒那麼好讀了。Python 提供一個重量級的武器 list comprehension 來解決這問題。比方說留下偶數並乘以三再加一:
In [1]: numbers = [1, 2, 3, 4, 5]

In [2]: [n * 3 + 1 for n in numbers if n % 2 == 0]
Out[2]: [7, 13]
綜合以上的語法,可以輕鬆地寫出易懂的 quick sort
def qsort(numbers):
    if len(numbers) <= 1:
        return numbers                                                                                     
    pivot = numbers[0]
    rest = numbers[1:]
    smaller = [n for n in rest if n <= pivot]
    larger = [n for n in rest if n > pivot]
    return qsort(smaller) + [pivot] + qsort(larger)
對於習慣 C、C++、Java 世界的人來說,應該不曾看過這麼直覺易懂的quick sort 吧。

tuple

tuple 是一個很妙的資料結構,它和 list 的主要差別是它是唯讀的,Python 裡鮮少有這種唯讀物件。不過它較易發覺的好處是被用在 Python 的parallel assignment 和函式傳回值。
於是在 Python 裡可以這麼寫:
a, b = b, a # swap
Python 在看到 b, a 時會產生一個 tuple 表示 (b, a),再透過 tuple 達到parallel assignment
函式也可以一次「傳回多個結果」:
In [1]: def divide_and_mode(a, b):
   ...:     if b == 0:
   ...:         return None, None
   ...:     return a / b, a % b
   ...:

In [2]: divide_and_mode(7, 3)
Out[2]: (2, 1)

In [3]: a, b = divide_and_mode(7, 3)

In [4]: a
Out[4]: 2

In [5]: b
Out[5]: 1
原理一樣是先轉成 tuple 再傳回,再視等號左側放什麼,決定要存成 tuple 或做 parallel assignment

2012-01-25 更新

應該沒什麼力氣更新續篇,在這裡簡短描述一下,有興趣的人可以找看看相關介紹。

with

在 Python 2.6 後,支援用 with 管理資源。像讀檔案可以用 with 的方式寫:
# 印出所有使用者的 id
with open('/etc/passwd') as fr:
    for line in fr:
        print line.split(':')[0]  
在進入 with 的 block 前,會呼叫 file object 的 __enter__ 以獲得 file descriptor;在離開 block 前會呼叫 __exit__ 關掉 file descriptor。即使中間呼叫了 sys.exit() 或丟出 exception,仍會執行到 __exit__,不用擔心會漏關。方便用在許多情境 (比方說 lock / unlock、自動 flush output buffer),易讀易用。

內建常用函式庫

除上述的基本資料結構和 string 外,還有 sqlitejson等。

簡單不易出錯的語法

舉幾個寫 C 可能發生的問題,但在 Python 的語法下則不會發生:
if (condition);
{
    // BUG!! 這裡的程式一定會被執行
}
if (x < 60)
    number_of_fail++;
    total_fail_score += x; // BUG!! 這行每次都會執行
另外,由於 Python 的 condition 只能是 expression,不能是 assignment。不會有 if (x -= 3 < 0) 這種 bug。

Reference:

http://fcamel-fc.blogspot.ca/2011/08/python-1.html

了解 C/C++ 程式行為的技巧

多數情況下我們會使用別人的程式,或是參與別人開發已久的程式,比較少是自己重頭撰寫所有程式。由此可知,了解程式行為的技巧相當重要,但是很少看到有書籍討論這部份的事,或許是因為很難理出一個主題吧。
下面以了解 C/C++ 程式為主,列出自己一些零散心得。

動態分析

在程式碼裡填入觀察碼
加入程式 log function call 是直接有效的作法,而且做起來不如想像的麻煩,詳見 《trace C/C++ function call 的方法》
或是找看看前人是否有了下除錯的 flag。有經驗的程式設計師在開發時必定有一套除錯方式,只是在正式使用時關掉了這些除錯功能,詳見《C/C++ 檢查和打開 debug 功能的小技巧》
附帶一提,自己開發程式時,除了留下除錯程式之外,記得要考慮使用 gdb 的影響,讓除錯程式更易於使用,詳見 《除錯小技巧: 在程式中直接中斷及偵測是否被 gdb 監控中》
觀察使用的函式庫
程式碼通常會用到第三方函式庫,有時我們可以從中得知一些線索,《python BaseHTTPServer 速度緩慢的原因》是一個簡短的例子,說明如何使用 ltrace 找出關鍵的第三方函式,繼而找出效率瓶頸。使用 ltrace 無須重編程式或加入 debug symbol。不過有可能讓程式變得不穩定,這時可使用 -l filename 只觀察部份函式庫,執行的時候會比較穩定一些。
其它兩則和 ltrace 相關的例子:
觀察使用的 system call
system call 是程式和 kernel 溝通的途徑,介面數量相對少,容易集中觀察。有時藉由觀察 system call 夾帶的參數,可以提供一些線索。比方說,不論上層函式如何包裝,開啟檔案最後會用到 open(),可以從 open() 的參數 找出程式目前使用的設定檔或 log 檔位置。或是像《用 strace 找出 Ubuntu 如何提示未安裝的指令》,使用 strace 觀察 system call 直接解答疑惑。
和 ltrace 一樣,無須重編程式也不用 debug symbol。更棒的是,使用 strace() 執行程式還滿穩定的。
其它 strace 相關的例子:
使用 gdb
debugger 的重要性無須多言,《gdb 初步心得》條列我常用到的指令。另外值得一提的是,有 core dump 的時候,core dump 裡一定會記錄產生 segmentation fault 的 thread,不用擔心找錯 thread,原因見《linux thread 與 signal》
編譯上線的程式時,多數會加上 -O2 最佳化效能,讓程式實際執行的狀況和程式碼有些出入。雖然如此,仍然可以加上 -g 觀察程式的 core dump,但要留意觀察的結果不見得是對的,詳見《debug info 和 optimization》。平時觀察程式行為還是用 -O0 -g 編譯較適當。
以下是其它和 gdb 相關的小技巧:
從 kernel 切入
有些情況下我們沒辦法從程式內部或 gdb 取得資訊,比方說程式莫明奇妙地收到 SIGKILL 而結束。由於程式無法攔截 SIGKILL,不方便查出凶手是誰。雖然可以在相關程式內直接對 system call kill() 設中斷點,但若凶手是外部程式,就沒輒了。
這種時候可用 SystemTap 直接從 kernel 內觀察是什麼程式請求使用 kill 送出 SIGKILL。我自己還沒有第一手經驗,這個例子是從同事那邊學來的,在這裡備忘觀察程式時,還可以用 SystemTap 觀察更底層的行為。

靜態分析

從執行檔找出關鍵字
《配合 c++filt 讀程式》說明如何從執行檔中找關鍵字,可藉此找出 UI 相關字串或是可能的函式名稱,有時比直接從程式碼下手容易。
找出 symbol 的定義或使用到 symbol 的程式碼
C 的情況比較單純,相關工具比較正確,也有工具可以產生精美的 call graph。但 C++ 的情況複雜許多,最後我決定無視 C++ 語法,直接找出所有和目標 symbol 有關的程式。《閱讀 C/C++ 原始碼的好幫手》有整理相關工具, 《查 C/C++ symbol 定義的方法》有一點關於我使用 gj 的方法。
使用 doxygen 產生 class 階層關係圖
大型專案會依功能切成數個模組,模組本身亦有一套自己使用 class 的方法。直接看程式碼容易陷入見樹不見林的困境。這時可用 class 階層關係圖協助了解整體架構。產生階層圖的方式見《用 doxygen 產生 class hierarchy diagram》。再輔以 gdb 產生 backtrace 觀察類別、模組之間的使用關係,比較容易明白整體架構。
善用編輯器或 IDE
目前是逐步學習如何強化用編輯器或 IDE 讀程式,加快在相關程式碼中探索的時間,還沒整理出一套完整的流程。
比方說用 gj 跳到某個使用函式 foo() 的檔案後,再來我會想知道目前在那個函式裡,《vim 顯示目前函式的名稱》就是針對此情境在 vim 內加了快速鍵做這這件事。或是像《使用 vim script 自動開啟 C/C++ 程式的標頭檔或程式碼》說明如何在 .h 檔裡按 F4 快速開啟 .c 或 .cpp 檔,或是反過來在 .c 或 .cpp 裡開啟 .h。
預防勝於治療
理解到了解程式是如此不容易後,行有餘力時,別忘了加強測試碼,讓日後使用相關程式的人更快進入狀況。良好的 unit tests 也是不錯的使用範例,有助於了解模組的行為。

核心分析

2014-01-05 更新。
現在來看,這段的概念才是理解大型專案時最重要的技巧。經驗愈多,愈覺得如此。說來容易做來難,需要累積經驗後才能體會。
想像自己會如何進行開發
有經驗的軟體工程師,做事的方式十之八九也差不多。特別是需求愈嚴苛,最後的解法也不會差太多。先自己想像可能的脈絡,之後比較容易縮小觀察目標,專注驗證自己的假設,並從驗證結果獲得新的契機製定下一步。
尋找原有專案的除錯工具
經年累月的專案必定有自己一套除錯工具,不然很難長期維護。有經驗的工程師應該也會在開發過程中研發出負責專案所需的除錯工具。所以,最有效觀察程式的方式,就是用原專案專用的工具。
對目標專案有一定了解後,可以自己想像,若自己進行同樣類型的專案開發,可能會做什麼輔助工具呢?有機會從中猜中切入點。

Reference:

http://fcamel-fc.blogspot.ca/2013/07/cc.html

What is SGID and how to set SGID in Linux?

This is next to SUID in our ongoing Linux file and folder permissions series. We already discussed about CHMOD, UMASK, CHOWN, CHGRP, SUID, StickyBit and SUDO concepts in our previous posts. In this post we will see

What is SGID?

Why we require SGID?

Where we are going to implement SGID?

How to implement SGID in Linux?

What is SGID?

SGID (Set Group ID up on execution) is a special type of file permissions given to a file/folder. Normally in Linux/Unix when a program runs, it inherits access permissions from the logged in user. SGID is defined as giving temporary permissions to a user to run a program/file with the permissions of the file group permissions to become member of that group to execute the file. In simple words users will get file Group’s permissions when executing a Folder/file/program/command.

SGID is similar to SUID. The difference between both is that SUID assumes owner of the file permissions and SGID assumes group’s permissions when executing a file instead of logged in user inherit permissions.

Learn SGID with examples:

Example: Linux Group quota implementation

When implementing Linux Group quota for group of people SGID plays an important role in checking the quota timer. SGID bit set on folder is used to change their inherit permissions to group’s permissions to make it as single user who is dumping data. So that group members whoever dumps the data the data will be written with group permissions and in turn quota will be reduced centrally for all the users. For clear understanding of this you have to implement group quota from the above link. Without implementation of SGID the quota will not be effective.

How can I setup SGID for a file?

SGID can be set in two ways

1) Symbolic way (s)

2) Numerical/octal way (2, SGID bit as value 2)

Use chmod command to set SGID on file: file1.txt

Symbolic way:

chmod g+s file1.txt

Let me explain above command we are setting SGID(+s) to group who owns this file.

Numerical way:

chmod 2750 file1.txt

Here in 2750, 2 indicates SGID bitset, 7 for full permissions for owner, 5 for read and execute permissions for group, and no permissions for others.

How can I check if a file is set with SGID bit or not?

Use ls –l to check if the x in group permissions field is replaced by s or S

For example: file1.txt listing before and after SGID set

Before SGID set:

ls -l

total 8

-rwxr--r-- 1 xyz xyzgroup 148 Dec 22 03:46 file1.txt

After SGID set:

Linuxnix-free-e-book
ls -l

total 8

-rwxr-sr-- 1 xyz xyzgroup 148 Dec 22 03:46 file1.txt

Some FAQ’s related to SGID:

Where is SUID used?

1) When implementing Linux group disk quota.

I am seeing “S” ie Capital s in the file permissions, what’s that?

After setting SUID or SGID to a file/folder if you see ‘S’ in the file permission area that indicates that the file/folder does not have executable permissions for that user or group on that particular file/folder.

chmod g+s file1.txt

output:
-rwxrwSr-x 1 surendra surendra 0 Dec 27 11:24 file1.txt

so if you want executable permissions too, apply executable permissions to the file.

chmod g+x file1.txt

output:
-rwxrwsr-x 1 surendra surendra 0 Dec 5 11:24 file1.txt

you should see a smaller 's' in the executable permission position.

How can I find all the SGID set files in Linux/Unix.

find / -perm +2000

The above find command will check all the files which is set with SGID bit(2000).

Can I set SGID for folders?

Yes, you can if it’s required (you should remember one thing, that Linux treats everything as a file)

How can I remove SGID bit on a file/folder?

chmod g-s file1.txt

Reference:

http://www.linuxnix.com/2011/12/sgid-set-sgid-linuxunix.html
http://stackoverflow.com/questions/5953169/avoid-having-subversion-modify-linux-file-permissions
http://stackoverflow.com/questions/1830131/weird-subversion-permissions-issue?rq=1
http://stackoverflow.com/questions/5836124/linux-permission-inheritance?rq=1
http://computernetworkingnotes.com/managing-file-system-security/sticky-bit.html
http://unix.stackexchange.com/questions/79395/how-does-the-sticky-bit-work
http://unix.stackexchange.com/questions/64126/why-does-chmod-1777-and-chmod-3777-both-set-the-sticky-bit
http://www.linuxnix.com/2011/12/sgid-set-sgid-linuxunix.html
http://www.bashguru.com/2010/03/unixlinux-advanced-file-permissions.html
http://stackoverflow.com/questions/14529325/how-to-remove-setgid-linux-unix
http://flylib.com/books/en/1.17.1.133/1/
http://www.linuxquestions.org/questions/linux-general-1/what-is-sticky-bit-mode-suid-sgid-258719/

http://en.wikipedia.org/wiki/Chmod
http://en.wikipedia.org/wiki/Sticky_bit
http://en.wikipedia.org/wiki/Setuid

http://computernetworkingnotes.com/managing-file-system-security/sticky-bit.html
http://ubuntuforums.org/showthread.php?t=1053885