星期二, 4月 27, 2010

Zend Controller- 常用動作

  1. Debug
    Zend_Debug::dump($row, $label = "current row", $echo = true);
  2. 不render view or layout
    • no render
      $this->_helper->viewRenderer->setNoRender();
    • disable layout
      $this->_helper->layout->disableLayout();
  3. BaseUrl, Controller or Action Name
    透過request取得
    $this->_request->getControllerName()
    ->getActionName()
    ->getParams() //取post或get之類的參數
    ->getBaseUrl()

  4. 轉頁動作
    • redirector,forward
      //給同一controller的 action (ex.index)
      $this->_redirect('Controller/actionA'); //要給完整的Controller及Action
      //=$this->_helper->redirector('actionA');  //如果直給action,會轉給此controller下的action
    • 轉給controllerA的actionA
      $this->_helper->redirector('controllerA/actionA');
      this->_forward('actionA', 'controllerA', null, array('param1' => 'xxx'));

    • $this->_redirect與$this->_helper->redirector的不同? Ans:_redirect需包("controller/action"), redirector可只下("action") ex.在TeeController下 $this->_redirect('index'); //會跑到Index/index,而不會是Tee/index $this->_redirect('Tee') // $this->_helper->redirector('index'); $this->_redirect('Tee/add'); // $this->_helper->redirector('add');
    • 保留訊息給redirect後的頁面
      //set
      $flashMessenger = $this->_helper->getHelper('FlashMessenger');
      $flashMessenger->addMessage($message);

      //get
      $message = $flashMessenger->getMessages(); //array
      if(count($message) == 0 )  
         $this->view->message = "";
      else
         $this->view->message = $message[0];
      }
    • 也可指定Namespace,透過setNamespace即可,範例如下 $flashMessenger->setNamespace('actionErrors');
    • redirect 給參數
      //add parameters
      $controller = 'index';$action = 'message'; $module = null;
      $parameters = array(    'para1' => 'test1',    'para2' => 'test2' );
      $this->_helper->redirector(action , controller , $module, parameters );

      //get parameters
      public function toNextPageAction(){
         $para1 = $this->getRequest()->getParam('para1');
         $para2 = $this->getRequest()->getParam('para2');
      }
    //宣告Registry變數 Zend_Registry::get("course", $course);
  5. 在controller裡,加入Header資訊
    • 加入Meta
      $this->headMeta()->appendName('keywords', 'framework, PHP, productivity');
    • js,css路徑(如果要直接在view裡加入看這)
      $this->view->headLink()->appendStylesheet(‘css/homepage.css');
      $this->view->headLink()->appendStylesheet($baseUrl.'/css/admin/tinybrowser.css');
      $this->view->headScript()->appendFile('/' . $file_uri);
    • 最後要echo資訊到header
      <html>
      <head>
        <?= $this->headTitle() ?>
        <?= $this->headMeta() ?>
        <?= $this->headScript() ?>
        <?= $this->headLink() ?>
        <?= $this->headStyle() ?>
      </head>
      <body>
        <?= $this->layout()->content ?>
      </body>
      </html>

zend 建立CRUD

Zend Framework version: 1.10
參考:Tutorial: Getting Started with Zend Framework 1.10

針對IndexController建立CRUD action
URLAction method
http://localhost/public/IndexController::indexAction()
http://localhost/add /IndexController::addAction()
http://localhost/edit /IndexController::editAction()
http://localhost/delete /IndexController::deleteAction()
分別輸入以下指令:
  • %zf create action add Index
  • %zf create action edit Index
  • %zf create action delete Index
這時除了建立各action的page外,還會自動在IndexController建立各action的動作
所以說如果是要針對UserController,最後的Index就改成User
以下是IndexController的內容
//controllers/IndexController.php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}

public function indexAction()
{
// action body
}

public function addAction()
{
// action body
}

public function editAction()
{
// action body
}

public function deleteAction()
{
// action body
}
}

vm二三事

VMware Tools
啥是VMware Tools
安裝在vm裡的虛擬os裡的套件

優點
  • 驅動vm裡面os顯卡等,像CentOS只能640 x 480和800 x 600
  • 可直接用滑鼠拖曳傳檔
  • 滑鼠可跨主機與vm視窗移動
  • 複製的東西可以在主機與vm視窗共用

 
安裝:
如何在CentOS安裝VMWare Tools?

組合exe,dll成單一執行檔 - ILMerge

寫好的程式常會include一些dll檔,每次copy給同事,就會發現漏掉dll沒給
查了一下 原來.net下有ILMerge 這好東西
下載:ILMerge

寫法
將aaa.exe跟bbb.dll及ccc.dll合併成Merged.exe
ILMerge.exe /out:Merged.exe aaa.exe bbb.dll ccc.dll
當然要先設環境變數囉
一般預設路徑C:\Program Files\Microsoft\ILMerge

另還有GUI
不過還是直接在建置事件那設定完最快了
每次compile完 就完成了...真是好東西
到Visul Studio的專案屬性裡的建置事件,如下圖












Error Code
  • 1: 發現是缺了要合併的檔案,補上就ok了
    • 不過有時也有其他問題,要log下來才知道 其他

Reference:
介紹好用工具:ILMerge (將多的 .NET 組件合併成單一組件)

zend - 建立layout

參考:Create A Layout
顧名思義就是套版型,Zend利用將網頁的header,body,footer拆開,方便header及footer可共用,不同的地方(即body),拆給MVC架構完成,所以最後要合併起來
Zend提供了二種做法:
Step1先從資料庫取出資料,Step2再轉成要呈現的資料


某些action不要有layout
將menu鏈結放在layout 則每頁都會有鏈結
但某些情況下,如嵌ifrmae 就不想再出現menu鏈結
就可以在該action下 加入這行
public function xxxAction(){
$this->_helper->layout->disableLayout();
}


加入在controller裡定義的標題資訊
在controller定義好要加入的標題檔資訊後,在layout加入echo的程式
<html>
<head>
  <?= $this->headTitle() ?>
  <?= $this->headMeta() ?>
  <?= $this->headScript() ?>
  <?= $this->headLink() ?>
  <?= $this->headStyle() ?>
</head>
<body>
  <?= $this->layout()->content ?>
</body>
</html>

星期一, 4月 26, 2010

zend 建立form

參考:Create A Form
跟使用者互動就透過form啦
1.建立form
指令:% zf create form Guestbook
Creating a form at application/forms/Guestbook.php
Updating project profile '.zfproject.xml'


// application/forms/Guestbook.php
class Application_Form_Guestbook extends Zend_Form
{
    public function init()
    {
        // Set the method for the display form to POST
        $this->setMethod('post');
 
        // Add an email element
        $this->addElement('text', 'email', array(
            'label'      => 'Your email address:',
            'required'   => true,
            'filters'    => array('StringTrim'),
            'validators' => array(
                'EmailAddress',
            )
        ));
 
        // Add the comment element
        $this->addElement('textarea', 'comment', array(
            'label'      => 'Please Comment:',
            'required'   => true,
            'validators' => array(
                array('validator' => 'StringLength', 'options' => array(0, 20))
                )
        ));
 
        // Add a captcha
        $this->addElement('captcha', 'captcha', array(
            'label'      => 'Please enter the 5 letters displayed below:',
            'required'   => true,
            'captcha'    => array(
                'captcha' => 'Figlet',
                'wordLen' => 5,
                'timeout' => 300
            )
        ));
 
        // Add the submit button
        $this->addElement('submit', 'submit', array(
            'ignore'   => true,
            'label'    => 'Sign Guestbook',
        ));
 
        // And finally add some CSRF protection
        $this->addElement('hash', 'csrf', array(
            'ignore' => true,
        ));
    }
}


2.建立對應action
指令:% zf create action sign Guestbook
Creating an action named sign inside controller
at application/controllers/GuestbookController.php
Updating project profile '.zfproject.xml'
Creating a view script for the sign action method
at application/views/scripts/guestbook/sign.phtml
Updating project profile '.zfproject.xml'
// application/controllers/GuestbookController.php
class GuestbookController extends Zend_Controller_Action
{
    // snipping indexAction()...
 
    public function signAction()
    {
        $request = $this->getRequest();
        $form    = new Application_Form_Guestbook();
 
        if ($this->getRequest()->isPost()) {
            if ($form->isValid($request->getPost())) {
                $comment = new Application_Model_Guestbook($form->getValues());
                $mapper  = new Application_Model_GuestbookMapper();
                $mapper->save($comment);
                return $this->_helper->redirector('index');
            }
        }
 
        $this->view->form = $form;
    }
}


3.設定view
<!-- application/views/scripts/guestbook/sign.phtml -->
Please use the form below to sign our guestbook!
<?php
$this->form->setAction($this->url());
echo $this->form;


完成啦,檢查一下http://localhost/guestbook/sign
應該會出現下圖

zend - 建model與database 連結


主要參考官網這篇Create a Model and Database Table

1.db設定檔
指令:zf configure db-adapter
以下各別為開發、測試及成品設定其db
//設定成品db
% zf configure db-adapter 'adapter=PDO_MYSQL&dbname="db_production"&host="localhost"&username="username"&password="ok1234"' production
//設定測試db    
% zf configure db-adapter 'adapter=PDO_MYSQL&dbname="db_testing"' testing
//設定開發db      
% zf configure db-adapter 'adapter=PDO_MYSQL&dbname="db_development"' development
設定完後的結果會存在application/configs/application.ini
所以...其實到application.ini改就可以
那些指令那記得起來...
完整的檔案如下
//application/configs/application.ini
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.view[]=
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = "ok1234"
resources.db.params.dbname = "db_production"
resources.db.params.driver_options.1002 = "SET NAMES utf8"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = "PDO_MYSQL"
resources.db.params.dbname = "db_testing"

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
resources.db.adapter = "PDO_MYSQL"
resources.db.params.dbname = "db_development"
中文亂碼問題
到application.ini中加入resources.db.params.driver_options.1002 = "SET NAMES utf8"
多個db問題
Zend_Application_Resource_Multidb
留著原本預設的db,才不用再改原本預設的資料

2.建立table物件
針對table(guestbook)建立對應table物件Guestbook.php
指令:% zf create db-table Guestbook guestbook
Creating a DbTable at application/models/DbTable/Guestbook.php
Updating project profile 'zfproject.xml'
Guestbook.php的內容如下
// application/models/DbTable/Guestbook.php
/**
* This is the DbTable class for the guestbook table.
*/
class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
{
    /** Table name */
    protected $_name    = 'guestbook';
}

3.建立Mapper
剛建立了table物件,在這要建立mapper
mapper的做用在處理insert,delete相關動作地方(要select的欄位,要下的where)
讓table物件與DB處理分開只負責存屬性(欄位)及方法,參考Data Mapper的觀念



% zf create model GuestbookMapper
Creating a model at application/models/GuestbookMapper.php
Updating project profile '.zfproject.xml'
// application/models/GuestbookMapper.php 
public function save($model);
public function find($id, $model);
public function fetchAll();
4.建立model
針對Guestbook建立該model
指令:% zf create model Guestbook
這指令會建立application/models/Guestbook.php
並更新project profile '.zfproject.xml'
// application/models/Guestbook.php
class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        $this->$method($value);
    }

    public function __get($name)
    {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        return $this->$method();
    }

    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }

    public function setComment($text)
    {
        $this->_comment = (string) $text;
        return $this;
    }

    public function getComment()
    {
        return $this->_comment;
    }

    public function setEmail($email)
    {
        $this->_email = (string) $email;
        return $this;
    }

    public function getEmail()
    {
        return $this->_email;
    }

    public function setCreated($ts)
    {
        $this->_created = $ts;
        return $this;
    }

    public function getCreated()
    {
        return $this->_created;
    }

    public function setId($id)
    {
        $this->_id = (int) $id;
        return $this;
    }

    public function getId()
    {
        return $this->_id;
    }
}

5.建立controller
指令:% zf create controller Guestbook

  • Creating a controller at application/controllers/GuestbookController.php
  • Creating an index action method in controller Guestbook
  • Creating a view script for the index action method at application/views/scripts/guestbook/index.phtml
  • Creating a controller test file at tests/application/controllers/GuestbookControllerTest.php
  • Updating project profile '.zfproject.xml'

=>會建立預設的index action
// application/controllers/GuestbookController.php
class GuestbookController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $guestbook = new Application_Model_GuestbookMapper();
        $this->view->entries = $guestbook->fetchAll();
    }
}

6.編輯view
<!-- application/views/scripts/guestbook/index.phtml -->
<p><a href="<?php echo $this->url(
    array(
        'controller' => 'guestbook',
        'action'     => 'sign'
    ),
    'default',
    true) ?>">Sign Our Guestbook</a></p>

Guestbook Entries: <br />
<dl>
    <?php foreach ($this->entries as $entry): ?>
    <dt><?php echo $this->escape($entry->email) ?></dt>
    <dd><?php echo $this->escape($entry->comment) ?></dd>
    <?php endforeach ?>
</dl>

總算結束了
鍵入http://localhost/guestbook 應該會看到下面畫面

vim常用指令

Vi Cheat Sheet

  • Get the name of the current file
    :echo @%def/my.txtdirectory/name of file
    :echo expand('%:t')my.txtname of file ('tail')
    :echo expand('%:p')/abc/def/my.txtfull path
    :echo expand('%:p:h')/abc/defdirectory containing file ('head')
  • 移動浮標指令

    Motion


    hMove left
    jMove down
    kMove up
    lMove right
    wMove to next word
    WMove to next blank delimited word
    bMove to the beginning of the word 單字字首
    BMove to the beginning of blank delimted word 單字字尾
    eMove to the end of the word 單字字首
    EMove to the end of Blank delimited word
    (Move a sentence back
    )Move a sentence forward
    {Move a paragraph back
    }Move a paragraph forward
    0Move to the begining of the line
    $Move to the end of the line
    1GMove to the first line of the file
    GMove to the last line of the file
    nGMove to nth line of the file
    :nMove to nth line of the file
    fcMove forward to c
    FcMove back to c
    HMove to top of screen
    MMove to middle of screen
    LMove to botton of screen
    %Move to associated ( ), { }, [ ]
  • 常用指令
    指令說明備註
    yy複製整行文字
    y$複製cursor後,到行尾文字
    gg=G格式化全文一直看人在寫gg=G
    還以為打gg或G都可以... 怎麼都試不出來...
    原來... 真的是打gg=G 靠... 試了好久... 機車
    gg - 到文章開頂端
    = - apply indentation (縮排)
    G - 到文章尾端
  • 分頁指令
    指令說明備註
    :tabnew開新分頁
    :tabedit path/to/file開啟舊檔
    Ctrl+6切換分頁
    gt依序切換
    :tabn,:tabp前後切換
  • 快速移動
    捲動螢幕
    ^F 往前捲動一個螢幕
    ^B 往後捲動一個螢幕
    ^D 往前捲動半個螢幕
    ^U 往後捲動半個螢幕

    重新調整螢幕位置
    z[enter] 將游標移到螢幕頂端
    zz 將游標移到螢幕中心
    z- 將游標移到螢幕底端


References

星期六, 4月 24, 2010

建立Zend Project

  1. prerequisite
    Zend 1.10要求PHP 5.2.4 or later.
    1. 先升級PHP
      #vi /etc/yum.repos.d/utterramblings.repo
    2. 輸入以下內容
      [utterramblings]
      name=Jason's Utter Ramblings Repo
      baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
      enabled=1
      gpgcheck=1
      gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
    3. 進行更新
      #yum -y update php
  2. 安裝Zend
    1.下載 http://framework.zend.com/download/latest
    #tar -zxvf ZendFramework-xx-.tar.gz   
    #mv ZendFramework-xx /var/www/zend //移到www下,順便重新命名
    2.設定php.ini
    #vim /etc/php.ini 
    -------------------------------------------
    //找到include_path那行,改成下面 
    include_path="/var/www/zend/library"
    貼心小叮嚀:要重啟httpd, #service httpd restart
    3.建立project (網站) 不知從哪一版開始 就像ror可下指令建立預設的資料結果
    #zf create project quickstart
    所有指令:Command Line Console Tool zf指令位於[Zend資料夾]/bin下,當然要自己去設定path才抓的到
    ln -s /var/www/zend/bin/zf.sh /usr/local/bin/zf
    錯誤訊息:當zf create project時,出現:PHP Fatal error: Class 'DOMDocument' not found in /var/www/html/Zend... 表示系統未安裝php-xml
    #yum install php-xml
    4.建立Zend Libraray 如果沒php.ini裡加的話,也可直接做link或複製一份到project下的library
先到剛建立的project下的library
      利用link
      #ln -s path/to/ZendFramework/library/Zend  
      直接copy一份
      #cp -r path/to/ZendFramework/library/Zend   
    5.Create a virtual host
    #vim /etc/httpd/[conf]/httpd.conf
    ----------------------------------
    <virtualhost *:80>    
      ServerName quickstart.local    
      DocumentRoot /var/www/html/quickstart/public    
      SetEnv APPLICATION_ENV "development"          
      <Directory /var/www/html/quickstart/public>      
        DirectoryIndex index.php      
        AllowOverride All      
        Order allow,deny      
        Allow from all    
      </Directory>  
    </virtualhost>
    6.確認是否成功 直接用browser開始127.0.0.1,看到下面畫面就是成功啦
    Reference

星期日, 4月 18, 2010

Code Complete 2

作者:Steve McConnell

Ch6 工作類別

類別基礎:抽象資料型別(ADT)
將字型大小變更為12點,即16個像素高
//易混淆
currentFont.size = 16; //不知是pixel還是點

//較具意義
currentFont.size = PointsToPixels(12); 
currentFont.bold = true;
currentFont.setBoldOn();

Ch7 高品質常式

從常式名稱中可猜出其作用
單一且明確定義的目的
參數不易超過7個,造成閱讀不易
具備抵禦錯誤資料,不會造成當機

良好的常式名稱
  • 描述常式的所有工作
  • 避免無意義、模糊式空泛的動詞命令
  • FormatAndPrintOut()會比HandleOutput()更加的清楚
  • 勿僅用數字后別常式名稱
  • part1(),part2()
  • 用回傳值述命名函式
  • printer.isReady(),user.next()
如何使用常式參數
  • 文件化有關參數的介面假設
  • 不要回頭再寫註解,數字參考單位,預期值的範圍、永不應出現的特定值
  • 考慮輸入、修改和輸出參數的命名慣例
  • input_,modify_,output_

Ch8 防禦性程式設計

用判斷提示證明和驗證前置條件及後置條件
又稱為design by contract (Meyer 1997)
function velocity(float latitude, float longitude,float elevation){
//Preconditions
Debug.Asert ( -90 <= latitude && latitude <= 90); 
Debug.Assert ( 0 <= longitude && longitude<= 360); 
Debug.Assert ( -500 <= elevation && elevation <= 75000); ... 

//Postcondition 
Debug.Assert()0 <= returnVelocity && returnVelocity <= 600);  
//return value 
return returnVelocity ; 
}

對於錯誤的條件,常式通常會用判斷提示直接處理錯誤的程式碼
判斷提示
Debug.Assert()0 <= returnVelocity && returnVelocity <= 600); 

直接處理錯誤的程式碼
...
//cloest legal value
if(latitude <-90) latitude = -90; else if (latitude > -90)
latitude = 90;
...

8.3 處理錯誤的技巧
傳回中性值
有時對錯誤資料的最佳反應就是持續操作,回傳預設值。數字計算=>0,文字操作=>空字串
關鍵情況下,就回傳錯誤,不要回傳錯誤的資料。
以下一個有效資料取代
處理資料串流時
傳回與上一次相同的回答
考慮建立集中的例外況報告程式
確保例外狀況處理一致性,也能提供中央儲存機制九
function reportException(string className, Exception ex){
string caption="Exception";
string message = 
"Exception: " + ex.Message + Enviroment.NewLine +
"Class: " + className + Enviroment.NewLine +
"Routine: " + ex.TargetSite.Name;

MessageBox.Show(message,caption);
}

//example
try{
...
}catch(Exception ex){
reportException(CLASSNAME,ex);
}

8.5 建立路障,避免程式內含錯誤造成的損毀
撰寫驗證類別,在所有介面運算資料前,透過驗證類別確保資料有效

Ch14 組織直線
14.1.須依特定順序排列的陳述式
1.連續呼叫相依的methods
//計算年營收前,得先計算季營收,而計算季營收前,要先計算月營收
revenue.ComputeMonthly(); //
revenue.ComputeQuarterly();
revenue.ComputeAnnual();
相依性不明顯,將來順序對換,會造成錯誤, 要讓程式碼可看出其相依關係
 2.初始化
//求各部門支出前,要先利用ComputeMarketingExpense()初始化
ComputeMarketingExpense(); //
ComputeSalesExpense();
ComputeTravelExpense();
無法在第一時間看出計算前要先初始化,將來順序對換會錯誤

使常式參數使相依性明顯 
//利用初始化及輸出值,提示相依性
expenseData = InitializeExpenseData(expenseData);

expenseData = ComputeMonthly(expenseData);
expenseData = ComputeQuarterly();
expenseData = ComputeAnnual();  

Ch15 使用條件式
15.1 if
指導方針
  • 先寫pass判斷的正常路徑;再寫異常案例後,避免模糊掉執行邏輯
  • 將正常的case置於if block, 而非else後方
OpenFile(inputFile, status); 
if( status = Status_Success )  //pass
    ReadFile( inputFile, fileData, status); //名目案例
    if(status = Status_Success)
    { 
        end(); 
        errorType= ErrorType_None;
    }
    else
        errorType = ErrorType_FileReadError; //錯誤案例
else
    errorType = FileOpenError; //錯誤案例
重點在讀取主要流程,而非費力專研例外案例
Ch26. 程式碼微調技巧
26.2 迴圈
決策外置(Unswitching)
如果if判斷不會在迴圈執行時變更,就把if搬到迴圈外

合併
將兩個相同集合項目的迴圈合併,一次就把兩次事做完
for(i=0;i<n;i++)
  a++;
for(i=0;i < n;i++)
  b++;
------------------------合併成------------------------
for(i=0;i < n;i++){
  a++;
  b++;
}

減少迴圈內的工作
要使迴圈有效率,其中的關鍵在減少迴圈內部的工作。
如果可在外部運算部份或全部的陳述式,只讓結果進入迴圈內,就可提升效率

26.3 資料轉換
使用整數而非浮點數
盡量不要使用陣列維度
減少陣列參考
利用變數存陣列值,就可避免在迴圈內讀取陣列值
for(...)
  rate[level] *= discount[type]; //discount[type]可抽出來
---------------------用變數取代---------------------------------
discounttype =  discount[type];
for(...)
  rate[level] *=  discounttype;

26.4 運算式
利用代數恆等式
not a and not b = not (a or b)
後者會比前者快上將近1份的時間
使用強度降代
  • 用加法取代乘法
  • 用乘法取代乘冪
  • 用三角恆等式取代三角常式
  • 整數運算會比浮點數快
  • 使用位移運算取代整數乘除

星期五, 4月 16, 2010

與熊共舞:軟體專案的風險管理 Waltzing with Bears: Managing Risk on Software Projects


與熊共舞:軟體專案的風險管理
Waltzing with Bears: Managing Risk on Software Projects

作者:湯姆.狄馬克、提摩西.李斯特/著












風險管理的主要活動
  • 風險探索(risk discovery):風險腦力激盪,把風險歸類,再訂出可長久運作的機製
  • 承擔分析(exposure analysis):以風險成形的機率,及其潛在的衝擊程度為基礎,量化每個風險
  • 應變規劃(contingency planning):萬一風險真的成形,你期望採取的行動
  • 紓緩(mitigation):在風險蛻變前必須進行的步驟,使事先規劃的應變行動在必要時能發揮作用
  • 蛻變的持續監視(ongoing transition monitoring):風險被納管之後,就要進行風險追蹤,留意是否成形

Ch8.將不確定性量化

- 風險圖
最早的完成時間會自動變成最後期限
但完成機率是零...
說定最中間的日期(5/1)
加減10~15%


Ch9.風險管理的技巧

  • 風險庫
  • 選擇偵測風險成形的指標
卡車司機的座右銘:
每個滾動的球後面都跟著一位追逐的孩童
並不是指都有孩童將被撞到,但看到球,還是立刻踩下煞車比較好

Ch10.風險管理的處方


如何做風險管理
  1. 透過風險抭索程序找出專案面臨的風險,彙整成風險調查報告
  2. 確定軟體專案的主要風險都已納入調查報告
  3. 針對每個風險,完成以下事項:
    • 命名風險,賦予唯一編號
    • 找出蛻變指標-能及早預告風險即將成形的事物
    • 預估風險成形對成本和時程的衝擊
    • 預估風險成形的機率
    • 計算時程和預算的風險承擔
    • 預先決定執行應變行動而必須預先進行的紓緩措施
    • 把紓緩措施納入專案計劃
    • 把所有細節記錄在類似附錄B的制式文件內
  4. 指出致命風險(showstopper)
  5. 假設不會有任何風險成形,估計最早完成日期(奈米機率日,N點)
  6. 參考自己或業界的不確定性係數,以N點為起點,畫出風險圖
  7. 利用風險圖表示出所有承諾,風跟規劃日期和預算有關的不確定性也標示出來
  8. 監視所有風險,注意是否成形或解除,一旦成形,便立即啟動應變計劃
  9. 在專案進行時,持續風險探索程序,以對付較晚才浮現出來的風險
承諾與目標
時程 = 目標 = N <=非常笨的做法
時程 > 目標 > N <=比較合乎情理

不確定性的取捨
如果交付日期已敲定,且不留任何延誤的餘地
可利用版本交付時程來達成


Ch13.軟體專案的核心風險

  1. 先天的時程錯誤(schedule flaw)
  2. 不把規模想清楚就敲定時程,逾期50%~80%不足為奇,主管很少會怪時程,相反地,會怪人沒有盡力
  3. 需求膨脹(requirement inflation) ... 沒完沒了的需求變動
  4. 每月合理的需求變更應小於1%,因此預留時間
  5. 人力流失(employee turnover)
  6. 技術人員的年平均流動率 接替人員完全進入狀況時間(ramp-up time)
  7. 規格崩潰(specification breakdown)
  8. 一般人傾向於促成案子,有談不攏的衝突都會先被掩飾起來,於是專案就在缺陷、模糊的目標下進行,但開發產品時就會爆發,通常是在專案後期,預算、時間都花光了。
  9. 低生產力(poor productivity)
  10. 開發人員的表現好壞差異相當大,但在團隊中,個人因素或多或少都會被中和掉,所以差異不大。
把核心風險當作風險管理是否完備的指標
不敢說核心風險是完善,但沒考量五個核心風險,就說有做風險管理....

Ch16.漸進式風險紓緩

預先採取的一套作為,萬一風險成形,便可有效地處理風險
漸進式式交付的好處:
  • 迫使為組件進行優先順序
  • 反暈真實的開發效率
交付計劃

  • 設計藍圖(design blueprint):顯示要實作的低階模組或類別,及彼此之間的關係
  • 工作分解結構(work breakdown structure, WBS):顯示要完成的工作,及彼此之間的相依關係
  • 一組版本驗收測試(version acceptance test, VAT):把產品的驗收測試按版本細分,顯示哪個測試可用在哪個中間產品上
實獲率
工作編號工作量工作百分比完成的版本小計VAT通過日期
1.11人週11%版本1
2.7人週7%版本1
3.12人週12%版本130%第100天
4.10人週10%版本2
5.9人週9%版本249%第154天
6.8人週8%版本3
7.13人週13%版本369%第173天
8.9人週90%版本478%第185天
9.14人週14%版本5
10.7人週7%版本5100%第206天

ch17 終極的風險紓緩策略
計劃準時參加會議,途中可能遇到預料外的耽擱,最簡單的做法只要提早出發...
假如專案交付日期非常關鍵,那麼早點出發才是真正的風險紓緩措施

星期四, 4月 15, 2010

PHP Framework - Zend

經過大師的開示
現在也準備以framework來開發專案
 看了半天挑了Zend來開發
  1. 安裝與建立Project

    References
  2. IDE
    Zend自已有利用eclipse改了一套Zend Studio,另外還有video教學
    不過要coco...還是用forever的vim吧...
  3. E.書及資源
    書或電子檔
References: PHP Framework 的效能比較 

十個最好的所見即所得編輯器

10 best WYSIWYG Text and HTML Editors for Your Next Project

嗯...都很棒
不copy原著的了...
不過留下10大的名稱,免得網頁不見了...
1. NicEdit
2. TinyMCE
3. CKEditor
4. YUI Rich Text Editor
5. MarkItUp!
6. FreeTextBox
7. MooEditable
8. OpenWysiwyg
9. Spaw Editor
10. jHtmlArea
給我最好的那個讓我抄就好...

星期四, 4月 08, 2010

jQuery的mouse座標

沒想到jQuery對mouse event的x,y就有很好的支援...
我還在努力的用javascript在event.x ..........

在element上的mouseover或click
Mouse co-ordinates within the element when mouseover or click an element
Relative Mouse Position

星期四, 4月 01, 2010

web效率評估

yahoo訂出的14條規則
  1. Make Fewer HTTP Requests
  2. Use a Content Delivery Network
  3. Add an Expires Header
  4. Gzip Components
  5. Put CSS at the Top
  6. Move Scripts to the Bottom
  7. Avoid CSS Expressions
  8. Make JavaScript and CSS External
  9. Reduce DNS Lookups
  10. Minify JavaScript
  11. Avoid Redirects
  12. Remove Duplicate Scripts
  13. Configure ETags
  14. Make Ajax Cacheable
還出firefox的評估外套
Yahoo! YSlow
http://developer.yahoo.com/yslow/


不要讓 JavaScript 拉長你網站的反應時間

Ruby

thread, fiber, continuation
  • thread
差不多...
不過可直接用...如程式中直接sleep...
不用透過thread去start
<code> while true do
    sleep 1;
    puts "take a break" //我沒有廣告嫌疑....
 end</code>
  • fiber
比較好的說法 協同常式 (coroutin)
我... 還是直接看範例吧
<code>f=Fiber.new{
puts "Fiber says Hello"
Fiber.yield
puts "Fiber says Goodbye"
}
puts "Caller says Hello"
f.resume
puts "Caller says Goodbye"
f.resume</code>
Output
Caller says Hello
Fiber says Hello
Caller says Goodbye
Fiber says Goodbye
reference: The Ruby Programmikng Language
  • continuation
類似basic的goto...其他的不想知道了

方法、proc、lambda與colsure

反射 reflection
延續伺服器 continuation server
<code>def loop
 for i in 1..5 do
  puts i
  callcc {|continualtion| return continuation} if i= =3
 end # cont.call returns here
 return nil
end
puts "Before loop call"
cont=loop()
puts "After loop call"
cont.call if cont
puts "After continuation call"</code>
結果
Before loop call
1
2
After loop call
3
4
5
After loop call
After continuation call

何時用
多部電腦之間同步的「請求 - 回應」溝通時
主線需暫停控制權,直到遠端系統回應之後再繼續
=>方便解決Http是stateless問題,不需用到session
ex. seaside web framework

看不懂說什麼嗎...
我也看不懂...