星期五, 6月 18, 2010

利用Zend_Navigation達到Menu、breadcrumbs及sitemap

主要做法就是在xml裡配置階層結構
步驟就照著reference的範例做
不過有遇到些問題,所以有問題的地方有特別註釋

1.設定Bootstrap.php
protected function _initNavigation()
{
$this->bootstrap('layout');
$layout = $this->getResource('layout');
//$view = $layout->getView(); //加了這行...會導致在layout.phtml呼叫helper會掛...所以..註解掉...
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav'); //指定要讀取的架構檔,命名為navigation.xml

$container = new Zend_Navigation($config);
Zend_Registry::set("Zend_Navigation", $container); //範例裡沒加,但沒加又跑不動...怪...
//$view->navigation($container); //嗯...也是能動咧...
}

2.編寫階層結構xml
path: application/configs/navigation.xml (xml檔名取命跟Bootstrap裡load的地方一樣)
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<nav>
<home>
<label>Home</label>
<uri>/</uri>
</home>
<courses>
<label>球場管理</label>
<uri>/courses/</uri>
<pages>
<add>
<label>新增球場</label>
<uri>/courses/add/</uri>
</add>
<edit>
<label>編輯球場</label>
<uri>/courses/edit/</uri>
</edit>
</pages>
</courses>
<about>
<label>關於我們</label>
<uri>/index/about/</uri>
</about>
</nav>
</configdata>

3.設定layout.phtml
<body>
...
<?php echo $this->navigation()->Menu()?>
<?php echo $this->navigation()->breadcrumbs()->setLinkLast(false)->setMinDepth(0)->render(); ?>
...

4.設定Controller
在每個controller的init裡加上以下程式碼
public function init()
{
//navigation
$uri = $this->_request->getPathInfo(); //原作是寫這樣啦,不過遇到有參數的uri就噴了
$uri = $this->_request->getControllerName()."/". $this->_request->getActionName(); //我把比對的uri改成這樣,也不怕最後有沒有斜線結尾

$activeNav = $this->view->navigation()->findByUri(strtolower($uri)); //避免大小寫問題,全轉為小寫
$activeNav->active = true;
//$activeNav->setClass("active"); //uri沒配對到時 會出現error,所以...
}


錯誤訊息
$activeNav->setClass("active");
出現Fatal error: Call to undefined method stdClass::setClass() ...
是因為uri對應失敗,所以無法設定class為active

xml裡放網站根目錄是比較正確的做法
不應該把會變動的前置資料夾放在裡面 ex. project/public
只不過這樣會導致zend_navigation產生的鏈結會從根開始跑 就會找不到位置

比較好的做法應該是該鏈結加上$this->_request->getBaseUrl()."/"
只是不知從哪去改... echo前去改...應該有更好的方法...找到再po上來

另外一個問題是如果... 鏈結需有必要的參數...
就還得要再將參數組成uri...

Reference
Zend_Navigation – creating a menu, a sitemap and breadcrumbs 用錄影的 不錯...

星期六, 6月 05, 2010

系統分析設計與實作 Week 9

Iteration 1
目的:將需求轉實作
=>要求都要配Controller
整合是持續性的在做整合

軟體開發方法
  1. Data-Orented
    易陷入細節,不易抓出圖
  2. Service-Oriented
    延展、彈性、重複利用


測試 unittest
功能性 => Controller
單元性 => Unit test, Business Object

User方面有UAT(User Acceptance Test)使幅者接受度測試

設計資料庫
設計表格
4大類 (人,事(event)/時,地物)
  1. 抓名詞(需求陳述中抓)
    但片斷,不易看到全貌,需求明確,才能完整
  2. 抓核心
    訂烏龜系統=>訂的event
    門禁管理=>刷卡的event (書UML.P148)
    儘可能容變動的需求
需求不再是主導系統的唯一來源
Enterprise => Transaction
Sub query易隱念企業邏輯,反而影響維

Q & A
  1. UML必要畫?
    UML是個語言,語言是用來溝通,所以獨立一個人開發時,基本上不用畫
  2. 交接時?
    需要時再畫,多一張就多需要維護成本
  3. 如何引導客戶提出需求
    客戶分1.Domain Expert可用活動圖(作業流程)或火箭圖
    2.Operator 直接用畫面UI溝通
    流程圖最好能當場畫,讓使用者確認,避免誤解
  4. CURD
    利用actor當授權

系統分析設計與實作 Week 7

烏龜訂購系統
phase 2 萃取穩定的結構共用元素(企業物件)
  1. middle ware
  2. controller
一開始不容易馬上判斷出來,可先放controller,再透過重構方式「逐漸萃取」
ex. 「計算訂購總額」應該放哪
hint: 推理,不要強記
「計算訂購總額」理論上放在訂購object上,但應該抽出到BO(企業物件),當共用的元素
過去,放store_procedure或script都不算好
但一開始要不容易抽,所以折衷先放controller
將來重構放到business object
=>將可共用的企業規則抽出

交易事件
人,(事/時),地,物
  1. 界定範圍
    利用UC,一般抓到5,6成就夠了
    • User Case View
    • Locial View
      -UC Realization
      -Class Model (配合codegen)
    UC都是片斷,有滿足即可,不要流程,至於滿足的程度依"Session"來判斷
  2. 撰寫UC敘述
    把「容易變」的跟「不容易變」的分開
    共用的可抽出來放
    =>產出Document
  3.  
  4. 實現UC (logical view realization)
    用UC Diagram當doc type
    *橋接實作,即建Conroller
  5. 建Controller
    設計可能會漏掉,由實作(feedback)去做調整,補足或修正Controller, UC Description
    隨時都在調,因此文件要少、精簡,過程中都是只是最後文件的snapshot

16.1.3.資訊系統的分層結構
  • 表達層(Presentation):UI
  • 中間層:CO(Control Object)
    DAO: 將DB存取細節放至DAO,任何跟DB有關的存取透過小弟DAO解決
    Adapter:外部系統的鏈結
    軟體主結構即抽出的概念性物件BO
  • 資料層:Database

三大物件
  1. Controller
  2. Boundary
    實體變動
  3. BO
    應付Domain變動,一開始不易抓,先放controller

循序圖不是要表達精細,重點在完成某功能時,反應run time的流程
EA做Sequence Diagram時,拉物件會要選擇"Simple link or Instance", 選instance,因為是物件
隱含的method用加雙斜線 ex.到db抓資料=>//select

不用每個UC都畫Sequence,只畫比較需要的
何謂需要
programmer無法看出必要的method(無共識時)
UI, Controller 應分開獨立的Project

系統結構面
Jobcason將結構分為
控制
實體
邊界
目的:好分類->好維護
結構只對developer有好處(好維護),User只看畫面

---
為何叫物件導向
都是用類別在定義,為何不是類別導向
心中想像的是物件在互動,而利用class描述出來,
ex. 作曲做的是音樂,但是得利用五線譜「作曲」記錄

安裝PHPUnit

phpunit官網:http://www.phpunit.de/

有兩個主要的版本,依php版本決定
  • PHPUnit 3.7 requires PHP 5.3.3
  • PHPUnit 3.8 requires PHP 5.4.7


兩種方法
  1. 直接使用phpunit
    https://github.com/sebastianbergmann/phpunit/

    <php
    include "phth to PHPUnit";
    class StackTest extends PHPUnit_Framework_TestCase
    {
        public function testPushAndPop()
        {
            $stack = array();
            $this->assertEquals(0, count($stack));
     
            array_push($stack, 'foo');
            $this->assertEquals('foo', $stack[count($stack)-1]);
            $this->assertEquals(1, count($stack));
     
            $this->assertEquals('foo', array_pop($stack));
            $this->assertEquals(0, count($stack));
        }
    }
    ?>
  2. 安裝phpunit
    wget https://phar.phpunit.de/phpunit.phar
    chmod +x phpunit.phar
    mv phpunit.phar /usr/local/bin/phpunit
    vi composer.json
    {
    "require-dev": {
    "phpunit/phpunit": "3.7.*"
    }
    }
    composer install
    程式裡加上
    require 'vendor/autoload.php';

其他PHPUnit官網寫很清楚,而且很多觀念教學,真棒

Zend View 常用動作

  1. jquery觸發submit
    $('form:first').trigger("submit");
  2. url路徑
    //根目錄 - 從web root到public
    $this->baseUrl('course/add'); //參數加入即會自動補
    =>/myweb/public/course/add
  3. 目前url
    $this->url(array('controller'=>'course','action'=>'add')); //如果當前的url是在同一個controller下的話,可以不用給controller參數
    =>/myweb/public/course/add/
  4. Controller, Action Name及參數
    $request = Zend_Controller_Front::getInstance()->getRequest();
    $controllerName = $request->getControllerName();
    $actionName = $request->getActionName();
    $paramArray = $request->getParams();
    $params = '';

    foreach($paramArray as $key => $value)
      $params .= $key . "/" . $value;
  5. 添加CSS 和 JS
    //將js,css放在public裡的js,css資料夾
    <script type="text/javascript" src="<?php echo $this->baseUrl('js/jquery-xxx.min.js');? >" >
    </script?>
    <link rel="stylesheet" type="text/css" href="<?php echo $this->baseUrl('css/xxx.css'); ? >" >
References
Zend - Get everything after base Url (Controller, Action, and any params)

zend DB 常用動作

直接對Zend_Db操作
  • 新增DB連線
    $db = Zend_Db::factory('Pdo_Mysql', array(
    'host'     => '127.0.0.1',
    'username' => 'webuser',
    'password' => 'xxxxxxxx',
    'dbname'   => 'course'
    ));
  • 下sql語法
    $stmt = $db->query('SELECT * FROM course');
    
    //Zend_Db提供fecth(),可抓出row object
    while($row = $stat->fetch()){
        echo $row['name'];
    }
  • 替換sql語法裡的參數
    $sql = 'SELECT * FROM course WHERE nam = ? AND status = ?';
    $stmt = new Zend_Db_Statement_Mysqli($db, $sql); //mysql就用mysqli
    $stmt->execute(array('demo course','display'));

宣告多個DB
  • 宣告(configs/application.ini)
    //db1
    resources.multidb.course.adapter = "PDO_MYSQL"
    resources.multidb.course.host = "localhost"
    resources.multidb.course.username = "root"
    resources.multidb.course.password = "ok1234"
    resources.multidb.course.dbname = "course"
    resources.multidb.course.driver_options.1002 = "SET NAMES utf8"
    resources.multidb.teegle.default = true
    
    //db2
    resources.multidb.admin.adapter = "PDO_MYSQL"
    resources.multidb.admin.host = "localhost"
    resources.multidb.admin.username = "root"
    resources.multidb.admin.password = "ok1234"
    resources.multidb.admin.dbname = "admin"
    resources.multidb.admin.driver_options.1002 = "SET NAMES utf8"
  • 選擇db
    $resource = $this->PluginResource('multidb');
    $resource->init();
    $db = $resource->getDb('course'); //取得course db
    $db->select()
        ->from( ... ) //多個from
        ->where( ... );

對Zend_Db_Table下指令
  • 設定table
    Zend_Db_Table::setDefaultAdapter($db);
    $courseTable = new Zend_Db_Table('course');
  • 在fetchAll裡加參數
    $resultSet  = $table->fetchAll(
            $table->select()
               ->where('status = ?', 'NEW') //有多個where就再下一次where(xx)
               ->order('id ASC')
               ->limit(10, 0)
    );
    
    //塞進array
    $entries   = array();
    foreach ($resultSet as $row) {   
        $object = row->id; // or row['id'];
        $entries[] = $object;
    }
  • 讓DbTable物件 讀非預設DB
    DbTable會預設讀config裡設定的"db"
    如果要讀一個db怎麼辦咧?
    1.註冊db
    在Bootstrap.php裡,註冊想要讀的db
    //application/Bootstrap.php
    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
    {
        $resource = $this->getPluginResource('multidb'); //假設存放在multidb裡,參考如何設定多個db
        $resource->init(); //初始化,不然不會動
    
        //註冊要讀取的DB - admin
        $admin = $resource->getDb('admin');
        Zend_Registry::set("admin", $admin);
    }
  • 2.改寫DbTable的建構子 方法一 就在DbTable的class下,override construct 把要給DbTable的物件參數中的'db'改成目前要讀的db
    class Application_Model_DbTable_User extends Zend_Db_Table_Abstract { 
        protected $_name = 'user'; 
        //方法一     
        public function __construct($config=array()){
            $this->read  = Zend_Registry::get('admin');
            $this->write = Zend_Registry::get('admin');
            $config['db'] = Zend_Registry::get('admin');                       
            return parent::__construct($config);
        }  
    
        //方法二  
        protected function __setupDatabaseAdapter(){ 
        } 
    }
    join
    //Build this query: 
    //  Select p."product_id",p."product_name", l.* 
    //  From "products" AS p JOIN "line_items" AS l 
    // ON p.product_id = l.product_id  
    $select = $db->select()->from (array('p'=> 'products'), 
    array('product_id','product_name'))->join(array('l' => 'line_items'), 'p.produt_id = l.product_id');
References
Zend Framework Certification Study Guide

星期五, 6月 04, 2010

jqueryui button

原來disable不是改tag屬性... (會失敗)
試了好久才發現要丟參數
利用.button( "disable" ), enable就一樣囉

星期二, 6月 01, 2010

星期二, 5月 25, 2010

jqgrid - search

我怎麼照官網做 都沒有search的結果
看官網的php 也不像會有search的結果...

最後還是上網找

server.php (同官網範例,就在下sql那段 加入這個)
$where = "WHERE 1=1 " . constructWhere();
$SQL = "SELECT ... FROM xxx $where ORDER BY $sidx $sord LIMIT $start , $limit";
...

//--------------------------
function constructWhere(){
  $wh = "";
  $searchOn = $_REQUEST['_search'];
  if($searchOn=='true')
  {
   $fld = $_REQUEST['searchField'];

   //過濾欄位,填入會用到search的欄位
   if(!( $fld=='id' || $fld =='name'))
   {
    $fldata = $_REQUEST['searchString'];
    $foper = $_REQUEST['searchOper'];

    //construct where
    $wh .= " AND " . $fld;
    switch ($foper) {
      case "bw":
        $fldata .= "%";
        $wh .= " LIKE '" . $fldata."'";
        break;
      case "eq":
        if(is_numeric($fldata)) {
          $wh .= " = " . $fldata;
        }else{
          $wh .= " = '" . $fldata."'";
        }
        break;
      case "ne":
        if(is_numeric($fldata)) {
          $wh .= " <> " . $fldata;
        }else{
          $wh .= " <> '" . $fldata . "'";
        }
        break;
      case "lt":
        if(is_numeric($fldata)) {
          $wh .= " < " . $fldata;
        } else {
          $wh .= " < '" . $fldata."'";
        }  
        break;
      case "le":
        if(is_numeric($fldata)) {
          $wh .= " <= " . $fldata;
        }else {
          $wh .= " <= '" . $fldata."'"; 
        }
        break;
      case "gt":
        if(is_numeric($fldata)) {
          $wh .= " > ".$fldata;
        } else {
          $wh .= " > '".$fldata."'";
        }
        break;
      case "ge":
        if(is_numeric($fldata)) {
          $wh .= " >= ".$fldata;
        } else {
          $wh .= " >= '".$fldata."'";
        }
        break;
      case "ew":
        $wh .= " LIKE '%".$fldata."'";
        break;
      case "ew":
        $wh .= " LIKE '%".$fldata."%'";
        break;
      default :
        $wh = "";
    }
  }
  return $wh;
}

Reference
忘了哪看的了...

接收完成的callback function
jQuery("#tbSearch").jqGrid({
  datatype:function(postdata) {
  jQuery.ajax({
  url: "server.php", //原本寫在外面的,現在外面那個就參考用
  data:postdata,
  datatype:"json",
  complete:function(xmldata,stat){
   if(stat=="success") {
    //xmldata是XMLHttpRequest, 所以如果是datatype的話,就要 xmldata.responseXML
    alert(xmldata.responseText);
   }
  }
});
},
...

Reference
Data Manipulation
jqGrid 的多字段查詢

星期二, 5月 18, 2010

zend - 關連table

我也不知道怎麼做出來的
一開始明明就照著教學做
可是怎麼做都說有錯
什麼No reference rule \"$ruleKey\" from table $thisClass to table $tableClassname"
不然就什麼 No reference from table $thisClass to table $tableClassname"
說xx table裡找不到reference關係...

最後進到Zend/library/Db/Table/Abstract.php一步步查
先看建構子有存進去了
最後一路看到getReference()
因為會說沒有rule 所以就先把那段解註掉
if ($ruleKey !== null) {
...
}

再看foreach ($refMap as $reference)...這段
明明有哇... 再把註解全拿掉時...
神奇的事發生了...
一切的值都有了 也不會有例外
這... 到底發生什麼事了...= =?

過程中 我是有一直亂改值測試...
可是... 最後成功的值...應該是一樣的
嗯哉~~ 總之先記錄下來.... 免得又遇到了

說明
table "GroupTee"裡有teeid,需要跟table "Tee"的主鍵id做關連
table grouptee
<?php
class Application_Model_DbTable_GroupTee extends Zend_Db_Table_Abstract
{
protected $_name = 'group_tee_rt';
protected $_dependentTables = array('Application_Model_DbTable_Tee'); // 對應到關連的 Table Class
}


table tee
<?php
class Application_Model_DbTable_Tee extends Zend_Db_Table_Abstract
{
protected $_name = 'tee'; //real table name

protected $_referenceMap= array(
'TeeName' => array( //rule名稱
'columns' => array('id'), //tee的pky
'refTableClass' => 'Application_Model_DbTable_GroupTee', //參考GroupTee
'refColumns' => array('teeid') //GroupTee裡的teeid
)
);
}


contoller或應用的地方
$tbGroupTee = new Application_Model_DbTable_GroupTee();
$group = $tbGroupTee ->fetchRow('id=1'); //取得第1個group
$grouptee = $group->findDependentRowset('Application_Model_DbTable_Tee','TeeName');
Zend_Debug::dump($grouptee, $label = "grouptee", $echo = true);



References
初探 Zend_Db_Table Relationships
One To Many Relationship with Zend Framework

星期日, 5月 16, 2010

dokuwiki - gcalendar

不知大家拿來做什麼用
公司是拿來當工作日誌用...
所以有分預定計劃,實際執行及Deadline
而event type當沒沒這麼巧的有這幾樣
不過可自定event type

作法
1.連結內容
=== 預定計劃 ===
*2010-5-3 - 2010-5-4 teegle
=== 實際執行 ===
*2010-5-3
=== Deadline ===
*2010-5-4


2.增加event type
到events.css增加與引用名稱相同的class名
path: [dokuwiki資料夾]/lib/plugins/gcalendar/user/events.css
/* 就是自己增加css的class */
.預定計劃
{
 color:grey; //改字型色彩
}
.實際執行
{
 background-image:url(images/gear.gif); //自行定義圖示
}
.Deadline
{
 color:red;
 bold:true;
 background-image:url(images/deadline.gif); //自行定義圖示
}


3.上傳圖片
就看自己寫到哪就傳到哪個資料夾囉
預設位置是[dokuwiki資料夾]/lib/plugins/gcalendar/user/images

結果如下
嗯 圖示的大小為15*16...
圖有點過大 不過效果還不錯...


Reference:dokuwiki - gcalendar

星期六, 5月 15, 2010

常用的10個jqgrid提示

網路上看的10 JQGrid Tips learned from my experience,再補點自己常遇到的

  1. Changing JQGrid width and height
    "//自動調寬度
    jQuery("#list2").jqGrid({
    autowidth: true, 
    ...
    //手動設定
    $("#list2").setGridWidth(200,true); //忘了true是什麼


    ColModel的屬性

    jQuery("#list2").jqGrid({
    ...
    colModel: [
    {
     name: 'rowid',  //將欄位名稱
     index: 'rowid asc, createddate', //click此欄位的排序會依據的order
      width: 50,
     sorttype: "int",
      align: "center",
     key:true, //將欄位設為pk
     search:true, //是否提供search
     hidden:false, //讓此欄位隱藏
    ...
  2. Grid without unnecessary scroll area
  3. Error due to missing locale file
  4. Callback function
    • loadComplete //ajax完成後的事件
      loadComplete: function(){
      var ids = jqgrid.jqGrid('getDataIDs'); //取得所有ids  
      alert(ids.length);
    • gridComplete //將所有資料讀進grid後的事件
    gridComplete及loadComplete差異
    $("#list").clearGridData();會觸發gridComplete
    利用ajax讀入資料時,jqgrida會先清掉grid內容,但不會觸發gridComplete,而讀完資料時,先後觸發gridComplete及loadComplete
    其他event
  5. Using pagers only for buttons (or icons)
  6. Hiding unwanted buttons in navigation bar
  7. Hiding the inline search by default
  8. Having your own icons for navigation bar buttons
  9. Removing title bar close button
  10. Adding toolbar    

常用指令
  • Get data from selected row
    var id = jQuery("#list2").jqGrid('getGridParam','selrow'); 
    if (id) {
        var ret = jQuery("#list2").jqGrid('getRowData',id); //3.6的方法
        //var ret = jQuery("#list2").getRowData(id);  //3.5以前的方法
        alert("id="+ret.id+" invdate="+ret.invdate+"...");
    } else {
        alert("Please select row");
    } 
  • 刪除
    //設定刪除事件
    $("#bDelete").click(function(){
    // Get the currently selected row
    toDelete = $("#mygrid").jqGrid('getGridParam','selrow');
    
    // You'll get a pop-up confirmation dialog, and if you say yes,
    // it will call "delete.php" on your server.
    $("#mygrid").jqGrid(
    'delGridRow',
    toDelete,
    { url: 'delete.php',
    reloadAfterSubmit:false}
    );
    });
    post資料有[oper] => del,[id] => 88
    Custom delete button in jqGrid

    //直接在navigator裡設刪除事件
    jQuery("#list2").jqGrid({
    ...
    }).navGrid('#pager2', {
    view: true,
    edit: true,
    add: false,
    del: true
    },{
       //依序view
    },{
        /edit
    },{
        //add
    },{
        //delete options 
        url: 'delete.php', //response的url
    
        //submit前驗證,其他看p.s.1
         beforeSubmit : function(id, formid) {
            if (id) {
               var ret = jQuery("#list2").jqGrid('getRowData',id);
               if (!(ret.xxx == "" )
                {
                    return [false,"xxx皆為空白才可以刪除"]; //false會顯示錯誤訊息
                }
            } else {
                return [false,"Please select row"];
            }
            return [true,""]; //true才會繼續
       
    }


    //刪除第12行row
    var su=jQuery("#list5").jqGrid('delRowData',12);
    if(su) 
        alert("Succes. Write custom code to delete row from server"); 
    else
        alert("Allready deleted or not in list"); 
    //清空grid內容
    $("#list1").clearGridData();


References

星期三, 5月 12, 2010

zend - 常見錯誤訊息

  • Action xxx does not exist and was not trapped in __call().
  • 大小寫都試過,最後換個全小寫名稱是成功了 還不知到底是什麼問題
  • Invalid controller specified (CourseTee)
    因為controller的名稱為2個字組合Course, Tee, 但zend不支援什麼駝峰字母,所以真正的名稱被改為Course-Tee 當利用zf create controller CourseTee時 會自動建立controolerview/script/course-tee
  • Zend沒有report error
  • Firefox 回報"伺服器要將此網址重新導向的要求無法完成"

星期二, 5月 11, 2010

jqueryui - dialog

在關閉dialog時 => $(this).dialog('close');
jqueryui會將input的內容清掉...
所以會抓不到.....
氣死... 搞好久才發現...

星期二, 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

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


星期六, 3月 27, 2010

dokuwiki

看大家推薦dokuwiki好用,而且新增套件很方便
就來安裝一下吧
官網:http://www.dokuwiki.org/

1.下載
實際操作一下 還真的很方便
直接給套件下載位置 ... download就完成了
wget http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2011-05-25a.tgz

2.安裝
tar zxvf dokuwiki-2011-05-25a.tgz
mv dokuwiki-2011-05-25a /var/www/html/doku


3.設定權限
太多了,所以用browser開啟 http://xxxxx/doku/install.php
會出現權限有問題的資料夾及檔案
到dokuwiki的安裝目錄一個個設定
  • dokuwiki/data
  • dokuwiki/lib/plugins
及之下的file權限也都改成777
應該就可以了
否則會出現新增失敗問題
There was a file copy error while attempting to install files for plugin
... the disk could be full or file access permissions may be incorrect xx

外掛篇
  1. 將內容做成線上投影片(deckjs)
    wow, 這真是好東西,拿來當週報報告還挺不錯的
    裝好後,只要在該頁加上
    ~~DECKJS~~
    就會在畫面出現個icon, 點開就會有投影片的效果
    真是好東西
    DokuWiki + Deck.js 打造超快速簡報發佈工具


References

DokuWiki Plugin 精選

MoinMoin、PmWiki和DokuWiki editor比較

星期六, 3月 20, 2010

Apache整合Tomcat

整合Tomcat 5.x
Linux下Apache與Tomcat整合的簡單方法

整合Tomcat 6.x
1.下載相關檔案
The Apache Tomcat Connector 隨意下載個mod_jk+版本號.so

2.so檔放到apache/modules文件夾裡面
3.修改apache/conf/httpd.conf 文件
...
還是看別人寫好的吧...

Reference
Apache 2.2 + Tomcat 6.0 + MySQL 5.0 + mod_jk 整合
apache tomcat6整合域名直接訪問
window 系統下 apache 2.2.6 + tomcat 6.0 整合工作配置

星期四, 3月 11, 2010

案例圖

目的:滿足系統外部的參與者對系統的某種預期
一個使用案例代表使用者在完成該期望後,就可以離開系統

界限(Boundary)
明確表達系統該關心與不應關心的部份

Reference
UML團隊開發流程與管理

UML應用時機

from UML團隊開發流程與管理

Ch2.企業流程與系統需求 (活動圖、案例圖)
1.瞭解企業流程
ex.記錄現在流程,如SOP
利用活動圖記錄大流程,幫助瞭解

2.取得系統需求
ex.使用者的需求
利用案例圖記錄大方向的系求需求,重心放在該功能需求的描述上
注意不是開發者想提供的功能
-利用使用者易理解的字眼來描述某功能需求
-描述是「目的性」,而非「操作性」
-明確指出相關人員及系統

Ch3.表達系統內部的結構
(類別圖、循序圖、溝通圖)
3.記錄關係
利用類別圖建立通盤性的瞭解

4.記錄流程
利用循序圖說明案例的流程中物件間的互動關係
溝通圖呈現物件結構與合作關係

Ch4.系統的微觀設計 (物件圖、狀態機圖、時序圖)
5.記錄特定時間點中,所有物件在系統的結構,如同某時間點的「快照」
ex.住院事件發生,有病人物件、主治醫生物件、住院醫生物件…
物件圖

6.有複雜的狀態轉換時
ex.病床需為empty才能住
利用狀態機圖描述狀態轉換的機制

7.超過特定時間,要改變狀態
ex.ATM操作
利用時序圖

Ch5.表達系統的鉅觀設計 (套件圖、互動概觀圖、複合結構圖)

活動圖

主要目的:陳述活動與活動之間的流程控制的轉移

適合用在描述企業的本質性的工作流程(Essential Workflow)
盡可能把「中介產出文件」(抱括表單、報表等)排除在外
不要落入活動的細節,需要的是整體業務流程的「大方向」
過早介入流程細節,需求收集容易陷入分析癱瘓陷阱

誤解
誤認活動圖中的活動是可以「共用」
因此想將相關活動併成一張活動圖使用
這會喪失活動圖的易讀性,也無法可顯「共用」的精神

資源的共用性很難透過活動圖來表達
活動圖的目的在表達流程的完整性,而非表達資源的共用價值
重點:活動是沒有共用性
繪製活動圖時,比較不容易綁手綁腳

設計原則
-目的在表達「流程完整性」,而非活動細節
-元素(主要是活動)不要考慮共用的議題
-繪製了「分派點」,則一定有個「會合點」
-盡量不要表達「文件」或是「資料」

Reference
UML團隊開發流程與管理

星期一, 3月 01, 2010

安裝JIRA跟Confluence

公司要建立issus tracking及KMS
被指派裝JIRA跟confluence
那就來吧...

安裝JIRA
1.設定jira.home
<install-dir>/WEB-INF/classes/jira-application.properties
就是儲放記錄的資料夾

2.啟動jira
到<install-dir>
下bin/startup.sh


有兩種裝法 一個是standalone版(包了Tomcat),一個WAR-EAR(要架在tomcat下)
1.JIRA Installation 官方教學
2.Linux下JIRA的安裝配置 //安裝standalone
*linux下的standalone不用裝tomcat
一時裝太快 把tomcat也建好了... (裝聰明)


安裝Confluence
一樣有standalone版跟WAR-EAR,一般會將Confluence跟Jira結合
1.Confluence Installation Guide 官方教學
2.如何將Confluence和JIRA standalone安裝到一起 window版
3.testlink+jira+confluence安裝 linux版
4.JIRA與Confluence的安裝與集成(1)
*設定confluence.home
就是儲放記錄的資料夾

注意事項
1.設定環境變數
export JRE_HOME=/usr/java/jdk1.6.0_18/jre
export JAVA_HOME=/usr/java/jdk1.6.0_18
CATALINA_HOME=/opt/apache-tomcat-6.0.24
CLASSPATH=$CATALINA_HOME/common/lib/servlet.jar
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$CLASSPATH
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH



2.設mysql connector
將使用mysql的驅動mysql-connector-java-5.0.3-bin.jar 放到/usr/local/jira/common/lib
一般的文檔都說放到這裡,但是後來發現應該放到/usr/local/jira/server/lib下


改DataBase
也有預設的db -HSQLDB
讓新手無痛安裝
不過建議指定其他的db
* SQL Server 2005
* SQL Server 2008
* MySQL
* PostgreSQL
* Oracle
* HSQLDB

錯誤
用jira發mail出現javax.mail.AuthenticationFailedException
=>mail設定錯了....一般是寄送的帳號或密碼打錯

星期四, 2月 25, 2010

委派時機

雖然知道delegate
但要說使用時機..還真不知什麼時候用

委派有用的時機:

* 當單一方法被呼叫。
* 當一個類別可能想要有該方法規格的多個實作。
* 當想要允許使用靜態方法來實作規格。
* 當想要事件形式的設計模式 (如需詳細資訊,請參閱事件教學課程)。
* 當呼叫者不需要知道或取得定義方法所在的物件。
* 當實作的提供者只想要將規格的實作「提供」給少數選取的元件。
* 當想要易於撰寫。

介面有用的時機:

* 當規格定義了一組會被呼叫的相關方法。
* 當類別通常只實作規格一次。
* 當介面的呼叫者想要轉換成或從介面型別上取得其他介面或類別。


Reference
委派教學課程

ajax跨Domain安全性問題

利用jQuery做ajax時
發現跨Domain時 會出現ajax error
查了一下才發現原來跨domain會有安全性的問題

AJAX的限制
  • 不能存取用戶端的任何檔案。
    ajax.open('GET', 'file://c:\\\\hello.html', ture); //錯誤
  • 不能存取不同來源位置的檔案 也就是網域(Domain)要相同
    更多解釋
Solution 利用JSONP來代替JSON.
  1. .client.html設定
    $.ajax({
      url: 'http://192.168.1.228/~kevyu/Testing/test.php',
      dataType: 'jsonp',                //1.將dataType定為jsonp
      jsonp: 'getAjaxData',
      data: {  callback: 'getAjaxData'}, //2.定義callback function
      error: function(xhr) {
        alert('Ajax request 發生錯誤');
      }
    });
    //3.這裡就是callback
    function getAjaxData(data){
       //alert(data);
       //alert(data.name);
    }

    新做法
    簡單多了,連callback function都不用設定
    最後加上callback=?,就這麼簡單,連jsonp都不用設
    $.ajax('returnJSON.php?callback=?', function(json) {
      //...
    }); 
  2. server.php設定
    還需server端配合,呼叫callback的function及回傳的parameter
    • 回字串
      <?php
        echo $_GET['callback']."('kevyu');"; //依callback的function名回傳kevyu字串
      ?>
    • 回json
      <?php
        $data = array("name"=>"kevyu", "gender"=>"male"  );
        $json=json_encode($data ); //編成json格式
        echo $_GET['callback']."({$json});"; //因為是json,所以要加"{ }"
      ?>

References
1.AJAX的安全性問題[筆記]
2.jQuery.ajax() 的 callback
3.Remote JSON - JSONP
1.用英文學英文
-發音
-文法 => 習慣 ex.常用字常不同,易分辯
-文化 (無相對字詞,就不要硬翻)

2.單字 (利用發音記)
-基本字 (1500~3000字)
-靠例句加深
-大量閱讀 500~1000字文章
查keyword
不查=>猜,畫線保留

Reading
速讀
1.強迫500字20秒
*不是讀,抓重點
2.計時(加強注意力)
閱讀=>將一個字一個字唸改成看,不是讀

1.讀句=>讀動詞
2.文章結構
首段 最後兩句是主題句
敘述 第一句
結論 第一句
1.這些是重點,有單字需要查才查,因為是keyword
2.或是重覆出現的字

星期一, 2月 22, 2010

檢查網路連線

You can check for a network connection in .NET 2.0 using GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

To monitor changes in IP address or changes in network availability use the events from the NetworkChange class:

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged


Reference
How do I check for a network connection

星期四, 2月 11, 2010

常用註冊值

更改windows授權的使用者名稱及組織名稱
利用ghostxp重灌後 開發的產品都是ghost的名字...
這東西釋出去好不太好看...
找了一下 還挺簡單的...
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\下的
RegisteredOwner //更改使用者名稱
RegisteredOrganization //更改組織名稱

第一隻ROR

照Agile Web Development with Rails寫的第一個範例
在這此抓出重要用到的指令









1.Build Project
rails demo //建立demo專案
cd demo


2.啟動server
ruby script/server //啟動server
//到http://localhost:3000下,檢查是否有啟動
//沒問題就可先關掉,準備coding


3.建立controller
ruby script/generate Controller Say
瞭解一下MVC架構 p29

4.建templete


...待續

星期三, 2月 10, 2010

利用scaffold做資料庫應用

天啊.遇到太多問題了
因為rails升到2.0有些語法不一樣
看書寫不出來,上網查才知道語法有不同了
而rails db:migrate又需與database溝通
所以事前也得先設定好...
練習第一個saffold做資料庫 還沒感受到 就先覺得好辛苦
不寫下來將來換個環境一定又忘了...
不過設定完... 還真的挺開心的 沒寫到任何sql所有欄位的新增、修改都做好了...
人說「頭過身就過」 希望接下來的路順一點...

建立專案
rails demo -d mysql //指定db可順便改好database.yml
1.設定資料庫
問題:解決rails的sqlite3.dll錯誤
沒有sqlite的dll是做呼叫sqlite的function...

問題:缺mysql
看範示的console畫面還想說~
哇~~跟mysql都整合在一起來
原來還是得自己先建立mysql環境
下載安裝mysql吧




2.scaffold
設定好資料庫就是來用scaffold
因為升級到rails 2的關係 所以下的參數會不一樣
1.0:ruby script/generate scaffold Movie Admin //直接指向Admin
2.0:ruby script/generate scaffold Movie title:string description:text one_sheet_url:string

Rails 2.0 scaffolding step by step.

3.rake db:migrate
這一步會遇到以下的問題
問題:syntax error on line xxx
一般來說是database.yml的設定出錯
冒號後面一定要有一個空白,否則會出錯!!
adapter: mysql
...
username:root <= 冒號後要空隔,不然會說argument錯誤

MySql問題
1.權限問題
解法:當然就要開放權限啦,另外注意不能用root

2.Commands out of sync; you can't run this command now: SHOW TABLES
-Mysql::Error: Commands out of sync; you can't run this command now: SHOW TABLES解决方案
-Rails2.1.0出现的问题undefined method `each' for
解法:從mysql/bin/目錄下找出libmySQL.dll,再copy到ruby/bin
*有時一樣會失敗,請注意抓的libmySQL.dll是跟MySQL server版本相同
我就抓了5.1.43的dll,連5.0.45... 問題一樣...硬是從5.0.45找出dll才pass


其他參考
第一個資料庫應用(with scaffold)--Ruby on Rails 完全新手手冊

星期日, 2月 07, 2010

來吧... Ruby

躲不掉的...
快讀吧...
先來名詞解釋

  • Ruby
    • 一種程式語言,如同C,Java
    • 所以不是只能寫網頁
    • 物件導向,類似Perl, Smalltalk, Python, Lisp
  • Rails-Web application framework
    • 用Ruby寫的
    • MVC架構
    • 利用convention替代掉大部份的設定
  • Active Record
    • Rails的ORM名稱
    • 與一般ORM不同的是Active Record利用convention替代掉大部份的設定
Ruby新手入門
Rails新手入門
第一隻ROR
不多說
直接看別人教學
實際做一次就會了
1.Ruby on Rails(Windows),從安裝到 Helloworld 2009/02 update
先簡單的做出Helooworld,不過重點在下一篇的scaffold
2.第一個資料庫應用(with scaffold)--Ruby on Rails 完全新手手冊
用scaffold才會感覺到ROR的方便,直接看Agile Web Development with Rails做範例感受更深,不過版本要看對...不然開發會很想打人

實際開發
遇到太多問題了...
自己也寫了一篇 第一隻ROR

討論
從 Django 看 Ruby on Rails 成功的原因

--------------------------------------
Reference
教學資源
安裝、應用
1.Ruby on Rails (ROR)入門第一站,InstantRails安裝圖文教學
2.在 Ubuntu 下部屬 RoR 環境


教學
1.ROR 的新手建議書單 from xdite
2.Ruby & Rails on Rails 進階書單
3.幾本不錯的Ruby和Ruby On Rails電子書下載
4.Top 13 Ruby on Rails Presentations
有書.... 就有電子書....
有電子書就...不用花錢買了... XD ...

Aptana IDE
官網:radrails
1.Get Rolling with Ruby on Rails in RadRails //標題還挺有趣的
2.5分鐘RadRails錄影教學

社群討論區,Blog
Ruby Taiwan 台灣的 Ruby 社群。
RailsFun!! Rails 討論區

Blog
Lighty RoR 介紹 Ruby,Ruby on Rails,JRuby
xdite

星期六, 2月 06, 2010

編輯Windows右鍵選單

常要開「裝置管理員」看USB有沒有連結
用regedit在「我的電腦」右鍵選單增加「裝置管理員」
出現「MMC無法開啟」...
"銀"了很久 一直沒處理
今天總算狠下心google找到解決方法了

@="裝置管理員"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\DevMgr\command]
"mmc.exe %%systemroot%%\\SYSTEM32\\devmgmt.msc"
改成"mmc.exe devmgmt.msc"



Reference:
用Reg在「我的電腦」右鍵增加「裝置管理員」、「服務」會出現MMC無法開啟的看這裡

星期五, 2月 05, 2010

InstallShield中 變更資料夾路徑的方法

OS:XP
InstallShield版本:2010

建立專案時
在Installation Design/Application Data/Files And Folders
將要封裝的Source資料夾"拉進"Destination資料夾
=>Sourece的路徑為D:\test (將test資料夾全部安裝到使用者的電腦)

後來想移動test資料夾至D:\Project\test,
因此Soure的路徑就需要更動,但找不到任何設定可以更動
惟一想到的方法就是刪掉舊的資料夾 再重新拉進
只是在Installation Design/Organization/Components 裡
已經為每個不同的資料夾取命了...
如此一來便得再重新命名...

後來跟原廠詢問
原來所有的變數路徑都儲放在Media / Path 下
也就是說在這裡就可以設定路徑了...

Sql字串有特殊符號

當字串裡有單引號如"It's good",或其他特殊符號時
Sql命令都會掛掉...
解決方法
1.在特殊符號前加入 \
"It's good"=>"It\'s good"
*透過mysqlconnector會發生錯誤...改用法2就沒問題了

2.遇單引號可再一個單引號
"It's good"=>"It''s good"

php可用直接呼叫
1.mysql_escape_string
2.mysql_real_escape_string
3.addslashes
至於差別...有看沒有懂...

星期日, 1月 31, 2010

日文學習

五十音還真不好背
背了一個忘一個
上網查五十音表時 看五十音平假名五十音片假名的由來
日文本來就是漢字去改的
利用一些字型和國、台發音 還挺好記..
現在都已經把五十音給背起來的 真是不錯的東西

看了五十音表 都是寫好的字
不知道筆劃,不會寫,寫了都怪怪的
五十音平假名書筆劃

背起來後還有小遊戲可以挑戰
類似以前學輸入法玩的小遊戲...叫什麼都忘了 哈

星期四, 1月 21, 2010

到底啥係native,strictfp,transient,volatile

雖然考過SCJP都不知道幾年了
不過要我解釋native,strictfp,transient,volatile
還是支支吾吾說不出來
下定決心要看懂這四大天"字"是什麼意思

1. native
簡單講,呼叫其他語言(c,c++之類)做出來的dll
做法
1.利用java做個介面供其他語言實作(也就是宣告成native)
2.用javah產出.h;
3.用其他語言實現native方法
4.編譯成dll
5.在Java中,再用System.loadLibrary()方法讀dll,就成功啦

還是看原作的範例比較快
認識理解Java中native方法

2. strictfp
意思是FP-strict,精確浮點,符合IEEE-754規範的,那為什麼不一開始就符合規範咧?
看wiki是這麼說地
In older JVMs, floating-point calculations were always strict floating-point, meaning all values used during floating-point calculations are made in the IEEE-standard float or double sizes. This could sometimes result in a numeric overflow or underflow in the middle of a calculation, even if the end result would be a valid number.

3.transient
為了避免把password等之類機密的資料序列化儲在永久媒體(如硬碟)
因此只要將該變數宣告為transient,就會禁止此變數被序列化
用過hibernate後,就更能瞭解是什麼了


4. volatile
每次被thread執行時,都強迫重讀宣告為volatile的變數。
什麼意思咧?如同synchronized鎖定function的意思一樣,而volatile可直接對特定變數
看volatile的例子

嗯 要尊重原作 我就不再copy-paste了
其實是懶得貼 哈

不過~~總算都懂了...ya~~

Reference
認識理解Java中native方法
Java關鍵字之native,strictfp,transient,volatile

星期二, 1月 19, 2010

jQuery 1.4出來囉

1月14是jQuery的四歲生日...所以出了1.4版
除了新方法外 還重寫了一些增強即有的功能

新功能
.delay()
太酷了...
/*二個div同時向上縮,first div先等個800毫秒
*這時second先淡入,再400ms後first div才淡入
*/
$("div.first").slideUp(300).delay(800).fadeIn(400);
$("div.second").slideUp(300).fadeIn(400);


舊function增加
.addClass()
function(index, class)A function returning one or more space-separated class names to be added. Receives the index position of the element in the set and the old class value as arguments.
//可以一次加多個class,或移除
$('p').addClass('myClass yourClass');
$('p').removeClass('myClass noClass').addClass('yourClass');

//還有更酷的 呼叫addClass時,動態加入class name
//就是Function Settter厲害的地方,其他.css(),.attr(), .val(), .html(), .text(), .append(), .prepend() ...也都有支援
$('ul li:last').addClass(function() {
return 'item-' + $(this).index();
});


jQuery.param()
直接將array轉成url參數格式

/*jQuery.param( obj ) 1.2
*jQuery.param( obj, traditional ) 1.4
*objAn array or object to serialize.
*traditionalA Boolean indicating whether to perform a traditional "shallow" *serialization.
*/
var myObject = {
a: {
one: 1,
two: 2,
three: 3
},
b: [1,2,3]
};
var shallowEncoded = $.param(myObject, true);
var shallowDecoded = decodeURIComponent(shallowEncoded);
--
a=%5Bobject+Object%5D&b=1&b=2&b=3
a=[object+Object]&b=1&b=2&b=3


寫到一半....
還是看別人整理好的比較快....
懶得寫了...

reference
New or Changed in 1.4
jQuery 1.4官方文檔中文版發佈
jQuery 1.4 小閱兵

星期一, 1月 04, 2010

書 - 完美程式設計指南

Ch2 自我維護
程式釋出前都要做unit test,即使是只改一點點

測試人員存在的目的是找尋程式員沒找到的錯誤,寫程式的人應該自己找尋自己製造的臭蟲。

coding時
1.用防禦性程式寫作,但別隱藏錯誤(bug)
2.加上除錯檢查(ex:assert) - 印出錯誤方便debug

*維護程式的發行版跟除錯版。發行版用來打包發行,除錯版用來盡可能快速抓蟲。
*除錯檢查巨集是寫出除錯檢查的快速方式。用它們來捕捉不應該發生的非法狀況。不要把這些狀況跟錯誤狀況混在一起;錯誤狀況在最後的產品中一定得被處理掉。
*用除錯檢查巨集來核對函式參數,並警告程式原有東西是未定義的。你愈嚴格定義你的函式,核對它的參數就愈簡單。
*一旦你寫好了一個函式,把它重新檢查一遍,並問問你自己,"我假設了什麼條件一定成立的嗎?"如果你找到一個假設條件,用除錯檢查巨集檢查這條件是否永遠成立,或者重寫程式以去除這樣的假設。也問問自己,"程式中哪裡最可能出錯,我怎樣才能自動找到錯誤?"盡可能將捕捉錯誤的測試放在愈早執行到的地方愈好。
*教科書鼓勵程式員防禦性的寫程式,可是記住這種寫作方式會隱藏錯誤。當你寫出防禦性的程式時,用除錯檢查巨集來提醒你自己是否有"不可能"發生的狀況發生了。

Ch3 增強子系統
檢查你的子系統,問問你自己,程式員們可能會怎麼誤用它。加上除錯維護敘述跟核對檢查來捕捉不好找跟常見的錯誤。

如果你不重複找尋,就修不好錯誤。找尋任何可能造成隨機行為的東西,把它們從除錯版程式中拿掉。將未初始化的記憶體以某個垃圾值填滿只是一種去除隨機行為的辦法,那樣子如果有參考到未初始化記憶體的情形發生,你就可以在每次執行到出錯的程式時都能重複同樣的現象。

如果你的子系統釋放記憶體(或其他資源)然後製造垃圾,請清理被釋放的記憶體中的內容,讓裡頭的東西看起來像垃圾;不然別處的程式可能會繼續使用這些已釋放記憶體中的東西而不被察覺。

類似的,如果你的子系統有些可能會發生卻不一定發生的行為,加上除錯碼來確定這些行為一定會發生。讓每件事都發生過可以增進你捕捉到較少執行到的程式中出現的怪異現象。

確定你的測試工作在程式員沒注意到時都在進行著。最佳的測試方式就是那些完全不用在乎它們的存在的測試。

如果可能,將測試碼建立在子系統裡頭,而不要寫在它們上頭。不要等到子系統已經寫好了,才來想辦法查對它們的動作正不正確。對每個你考慮的設計方式,問問你自己,"我該怎樣徹底查對這個實作?"如果你發現幾乎不可能或難於測試這個實作方式,好好考慮一下是不是該換個設計方式,即使那表示拿程式大小跟執行速度為代價來讓系統可被測試。26

在拿掉一個讓程式跑得很慢或吃很多記憶體的查核測試前,多想一遍。記住,查核程式碼不會出現在發行版的程式裡。如果你發現自己想著,"這些測試太慢了(或太大了)",停下來,問問自己,"我該怎樣讓這些測試繼續留著,而讓程式跑快一點(或變小一點)?"

星期日, 1月 03, 2010

Python開發

什麼是Python? Why Python?
* Python基礎教學
* Python入門教學
* Python進階教學
* Python程式範例
* Twisted教學
* TurboGears教學
* Eclipse 的 Pydev IDE教學

這裡有教學
從基礎到進階都有 真不錯
版主真有心
連Eclipse的安裝都有了
而且是圖文教學 「足感心ㄟ」

星期三, 12月 30, 2009

餐廳列表

每次想吃什麼都想不到
事後想起才覺得可惜 忘了這間
先寫好 以便日後查詢...改名叫"魚乾的美食筆記本"好了

台北
墨西哥料理

佬墨日出-Tequila Sunrise
墨西哥餐飲美味道地,經典的仙格麗亞,順口的瑪格麗特,香脆玉米片搭配勁辣爽口瀟灑醬


義大利麵

La Pasta

中式熱炒
新東南活海鮮料理
鮮納肚~100元快炒店(東區)

星期三, 12月 16, 2009

Facebook 二三事

FBML
json_encode問題~ php有些版本不支援
但只要引用facebook.php 就會有了
require_once 'facebook.php';

FBJS
當只有script時,一定要有個內文,script才會執行
echo "test
<script> function go(){
//xxx
}
go();
</script>";


showPermissionDialog說有ondone,但加了會掛...拿掉反而可以執行..怪
Facebook.showPermissionDialog('publish_stream');