Ví dụ về cách ước lượng dự án bằng phương pháp FPA (phần I)

Giả sử chúng ta cần lượng giá cho ứng dụng My E-books Lib. Đây là một ứng dụng cho phép bạn quản lý những cuốn ebooks mà bạn đã, đang và dự định đọc, hoặc thậm chí là những cuốn bạn chỉ muốn… sưu tập cho đủ số lượng.

Sách không tự sinh ra và cũng không tự mất đi. Do đó, gì thì gì, bạn cũng phải đi mua sách đã. Ứng dụng có chức năng là “Buy an E-book“. Gọi là mua cho oai thôi nhe, đừng tưởng thiệt mà chạy ra ACB, reg một cái Visa Debit card về rồi thì có nước ngồi… ngắm! Chức năng này đơn giản thôi, có 1 field Textbox dùng để nhập Title, ISBN, Author… hay bất cứ gì cũng được. Một cái Button “Search”.

Vậy rồi… search ở đâu, search bằng niềm tin àh! Oh, yeah… quên mất! Chúng ta sẽ sử dụng dịch vụ của Amazon. Okie. Type “gì gì” đó vào textfield, ứng dụng sẽ “tà tà” hoặc “vùn vụt”  (tùy vào sự hào phóng của anh VDC, FPT hay anh Viettel) tới đập cửa Amazon réo “Ê ê, mày có cuốn sách nào mà có cái tên là ‘gì gì‘ đó không?”. Anh Amazon rất là thân thiện, cười nhe hàm răng trắng bóng được chải bằng bàn chải Colgate với kem… Close-up Whitening, miệng nói tay… quăng cho một list dài dằng dặc “Này thì ‘gì gì‘ mà anh cần tìm đấy! Lần sau có nhờ thì nói rõ rõ một xíu nhóa”. Ô hô hô, một đống hầm bà lằng, nào là Title, nào là ISBN, nào là Publisher, nào là Author… thôi kệ, rút kinh nghiệm đợt sau sẽ type chi tiết hơn. Đại loại sẽ type là “Kamasutra” thay vì type mỗi “gì gì“. Hơ hơ. Sau một thôi, một hồi bới tung đống hầm bà lằng cũng tìm được cuốn “Kỹ thuật ‘gì gì‘ “! Nhấn nút “Add to My Lib” để thêm sách vào thư viện thôi.U…raaaaa công viên chơi nào!

À, mà nhớ tick vào cuốn sách “Kỹ thuật gì gì” rồi mới nhấn nút “Add to My Lib” nhé! Vậy là xong quá trình “mua” sách. Oh, yeah! (Anh Amazon chắc cũng tức trào cơm). Makeno, việc thường ngày ở huyện í mà!

Mua sách xong, nếu thấy háo hức quá thì đọc ngay kẻo “nguội”, nếu chưa muốn đọc thì cứ để đấy đợi hôm nào “trời hồng hồng, nắng trong trong” thì đem ra… phơi, còn nếu hôm qua đã xem “cọp” được của thằng bạn mấy “positions” thì cũng bảo là đang đọc nhé. Còn nếu hôm qua đã “trót” xem hết rồi, nhưng cũng muốn mua về để khi “không thuộc bài” thì có thể lấy ra mà nghía, okie, không sao… Cứ thế mà thiết lập trạng thái (Set Status) cho cuốn sách là “Reading“, “Plan to Read“, “Finished” tương ứng.

Trong quá trình đọc, nếu thấy “kỹ thuật” nào hay thì có thể ghi chú (Noting) lại nhé! Ê, này, này! Gì mà “đắm đuối” thế chứ hả! Đừng thấy “hay” quá mà đọc liền một mạch hết cuốn luôn nha! (Hehe) “Tẩu hỏa nhập ma” bây giờ. Đọc mỗi ngày một tí, một tí tẹo thôi, ghi chú đàng hoàng những lời “khắc cốt ghi tâm”, những “bí kíp”, những lời “vàng ngọc”, “giác ngộ chân lý” của mình… Khi nào tạm ngừng đọc, thì đánh dấu (Paging) số trang lại. Hôm sau nếu rãnh thì lôi ra đọc còn không thì hôm sau, nếu hôm sau của hôm sau lại bận thì có thể để hôm sau của hôm kia đọc cũng không muộn! Yeahhh!

Ứng dụng nho nhỏ mà tui mô tả đến đây là hết rồi! Cảm ơn các bạn đã “căng sức” theo dõi! (Vỗ tay). Thấy ứng dụng mà tui mô tả có “trong sáng” và “rõ ràng” chưa nào!

Yahoo! 360 to Shut Down – cái chết của một ngôi sao!

Với cộng đồng dân cư mạng VN, đúng ra vào thời điểm này Yahoo!360 sẽ kết thúc sứ mạng “lịch sử” của mình, chấm dứt hơn 4 năm khoấy động giới trẻ VN.

yahoo!360 to shut down“Yahoo!360 – memories” – trào lưu mới hiện nay

Ra đời vào những ngày cuối tháng 3/2005  và chính thức mở cửa với cộng đồng sử dụng Internet trên thế giới vào tháng 6, Yahoo!360 đã có những ảnh hưởng cực kỳ lớn đối với đời sống của đại bộ phận giới trẻ VN. Tuy những tính năng mà Yahoo!360 cung cấp chỉ ở mức “làng nhàng”,  “thường thường bậc trung”, song nhờ công cụ chat Yahoo Messenger “chống lưng”, Yahoo!360 dễ dàng và nhanh chóng chiếm lĩnh thị trường và trở thành  mạng xã hội hàng đầu ở VN. Thậm chí, sau đó, hàng loạt Mạng xã hội ra đời, trong nước có, ngoài nước có…, với những tính năng nổi trội hơn, song cũng không phải là kẻ đối trọng của Yahoo!360…

Vì một số lý do, Yahoo!360 tuyên bố chính thức đóng cửa sau nhiều lần ra… “đòn gió”. Quyết định này không quá bất ngờ với dân cư mạng, bởi suốt một năm nay, người dùng luôn phải “chịu đựng” những lỗi khó chịu từ một hệ thống quá “đát”, thiếu sự chăm sóc và quan tâm đúng nghĩa từ phía nhà cung cấp. Đại bộ phận đã “lục tục” tìm cho mình một ngôi nhà mới trên 360plus, facebook… Dù vậy, dân cư mạng VN vẫn dành một tình cảm nhất định cho Yahoo!360 cho  tới khi…

Yahoo!360 tuyên bố người dùng VN sẽ được gia hạn tới ngày 19/8 cho những nỗ lực “chuyển nhà cuối cùng”! (Yahoo! 360 gia hạn thời gian đóng cửa đến 19/8Dân Trí) Một thiện chí từ phía nhà cung cấp chăng?  Tuy nhiên, sau ngày 13/7 người sử dụng sẽ không cập nhật được các bài viết trên blog của mình. “Thà biến mất vào thời điểm này còn chút gì đó lưu luyến. Giờ cho thêm 1 tháng nữa cũng chả làm dc cái gì.” hay như “Tạm biệt cho đã giờ kiu gia hạn. Bó tay” – Pikachu, một blogger nhận xét.

Tuy nhiên, ngoài chuyện “dời nhà”, đây là cơ hội để bạn tham gia trào lưu “Yahoo!360 Memories”, tranh thủ chụp lại những thời khắc cuối cùng trên blog cá nhân.

yahoo!360 memories

Một cái chết tốn nhiều giấy mực!!!

PHP Test tools: How to use SimpleTest in Eclipse (part 1)

Cài đặt SimpleTest trong Eclipse

  • Cài đặt từ Remote Site

  • Cài đặt từ Local Site

Cấu hình SimpleTest trong Eclipse

  1. Chọn Window > Preferences… trên menu bar
  2. Chọn “Simple Test” trong danh mục liệt kê bên tay trái.
  3. Nhập hoặc chọn đường dẫn tới file php.exe
  4. Nhập định dạng file cho file dùng để test. Ví dụ “.php” hooặc “.test.php”.
  5. Click OK.

Sử dụng SimpleTest trong Eclipse

  • Tạo mới một PHP Project với tên là Test gồm các thư mục con:
    • Test\classes: dùng chứa các class cần test.
    • Test\test: chứa các file test.
  • Tạo files Calculator.php trong thư mục ‘classes’.
<?php
class Calculator{
  function add($x, $y){
    return $x + $y;
  }

  function subtract($x, $y){
    return $x - $y + 1; // Hiện thực sai
  }
}
?>
  • Tạo file testCalculator.php trong thư mục ‘test’.
<?php
require_once(dirname(__FILE__). '/../classes/Calculator.php');
class testCalculator extends UnitTestCase {
	function test_exists(){
		$url = dirname(__FILE__);
		$this->assertTrue(file_exists($url . '/../classes/Calculator.php'),"File not existed at $url");
	}

	function test_add(){
		$cal = new Calculator();
		$result = $cal->add(1,2);
		$this->assertEqual(3, $result, "Passed");

	}

	function test_subtract(){
		$cal = new Calculator();
		$result = $cal->subtract(1,2);
               $this->assertEqual(-1, $result, " Value what we expected is '-1' is not equal '$result' which is returned from subtract function");
	}

}
?>
  • Chọn Run As > Simple Test (hoặc tổ hợp phí Alt+Shift+X, G). Hộp thoại kết quả sẽ xuất hiện như sau:
Failed Testing

Failed Testing

  • Cửa sổ kết quả cho thấy phần hiện thực hàm “subtract” của lớp Calculator đã hiện thực sai. Sửa lại file Calculator.php như sau:
<?php
class Calculator{
  function add($x, $y){
    return $x + $y;
  }

  function subtract($x, $y){
    return $x - $y + 1; // Hiện thực sai
    return $x - $y;
  }
}
?>
  • Chọn Run As > Simple Test, kết quả như sau:
Passed Testing

Passed Testing

Một số lưu ý:

  • Không có yêu cầu cụ thể đối với việc đặt tên file dùng để test (nhưng nên theo chuẩn).
  • Tên function trong file test (cụ thể là testCalculator.php) phải bắt đầu bằng tiền tố “test” (không phân biệt chữ viết hoa hay chữ viết thường).
  • Có thể test trực tiếp qua browser, khi đó:
    • Download và giải nén gói simpletest ở trang http://simpletest.org/en/download.html
    • Chép thư mục simpletest vào trong thư mục Test/test/ chung với file testCalculator.
    • Thêm dòng lệnh sau vào đầu file testCalculator.php:
          require_once(dirname(__FILE__) . '/simpletest/autorun.php');
    • Mở browser (IE, Firefox, Safari…) gõ vào url  sau đây, trường hợp của mình file testCalculator nằm trong thư mục /demo/Test/test/:
          http://localhost/demo/test/test/testCalculator.php
    • Kết quả sẽ như sau:

    Passed Testing in Safari Browser

    Passed Testing in Safari Browser

Resource:

  • http://simpletest.org/eclipse/readme.html

PHP test tools: SimpleTest or PHPUnit

Trang opensourcetesting.org giới thiệu 9 công cụ hỗ trợ tiến trình Unit Test đối với lập trình PHP gồm có:

  • Amock
  • izh_test
  • PHP Assertion Unit Framework
  • PHPUnit (dựa trên nền tảng JUnit)
  • PHPUnit (trong gói PEAR)
  • Simple Test
  • Spike PHPCheckstyle
  • Spike PHPCoverage
  • Testilence.

Tuy nhiên, căn cứ vào số lượng download, có thể thấy nổi bật lên trong số đó chính là Simple Test (>100k lượt) và PHPUnit (>35k lượt).

Simple Test chủ yếu được phát triển bởi Marcus Barker và một số thành viên khác trong khi đó PHPUnit được phát triển bởi  Sebastian Bermann dựa trên nền tảng của JUnit nên có vẻ phát triển ổn định và được hỗ trợ bởi một cộng đồng lớn hơn so với Simple Test. Điều này thể hiện qua việc việc PHPUnit đã đưa ra phiên bản 4.0 so với phiên bản 1.0.1 của Simple Test.

Vậy chúng ta cần gì ở một PHP test tools:

  • Hỗ trợ mô hình test tăng dần, cho phép tạo các test case trước khi triển khai.
  • Hỗ trợ quá trình test qua browser hoặc command-line.
  • Có thể thực hiện cả việc test độc lập, theo nhóm và các bài test tổng thể
  • Có thể customize phần hiển thị kết quả.
  • Cho phép kiểm tra cấu trúc của lớp.
  • Kiểm tra các biệt lệ và sự kiểm soát biệt lệ.
  • Cung cấp các plug-in để tích hợp với IDE

May thay, cả SimpleTest và PHPUnit đều đáp ứng được hầu hết những yêu cầu đó. Tuy nhiên, mỗi công cụ cũng có những ưu và nhược điểm riêng:

Về phía PHPUnit.

  • Ưu điểm:
    • Được sử dụng và hỗ trợ rộng rãi từ cộng đồng  Zend: Cập nhật thường xuyên, mức độ lỗi ít, tài liệu chi tiết.
    • Có thể tạo nhiều loại report khác nhau.
  • Khuyết điểm:
    • Mock Objects được đưa ra trong phiên bản PHPUnit 3 song vẫn chưa thể sánh bằng SimpleTest
    • Không thực thi trực tiếp từ browser.
    • Ít chức năng hơn Simple Test

Về phía SimpleTest.

  • Ưu điểm:
    • Hỗ trợ Mock Objects mạnh mẽ
    • Hoạt động chung với PHPUnit
    • Có thể thực thi trực tiếp từ browser lẫn command-line.
    • Có thể test cả hành vi lẫn trạng thái của đối tượng.
    • Người dùng  Drupal có thể cài đạt module để sử dụng SimpleTest
  • Khuyết điểm:
    • Phần tài liệu không bằng PHPUnit
    • Cần thêm sự bổ sung mở rộng để dùng chung với Zend Framework

Mock Objects mô phỏng lại các đối tượng thực sự trong ứng dụng, chúng cũng có các phương thức giống như các đối tượng mà nó mô phỏng, chính vì vậy nó thường được tạo ra nhằm kiểm tra tính đúng đắn của một đối tượng phụ thuộc vào đối tượng mà nó mô phỏng.

Như chúng ta đã biết, trong các ứng dụng, một đối tượng thường phụ thuộc vào sự tồn tại của một (hay nhiều) đối tượng khác, chính vì vậy sẽ gây ra trở ngại khi phải thực hiện công đoạn Unit Test (mục đích là cách ly các thành phần của ứng dụng).

Giả sử có class StudentBSO cung cấp các business services cho các đối tượng Student và sử dụng StudentDAO để lưu dữ liệu vào database. Khi muốn test class StudentBSO, chúng ta chỉ cần gọi đối tượng mock object mô phỏng đối tượng StudentDAO, thực hiện triệu gọi các phương thức với các đối số tương ứng (đã được xác định) nhằm đạt được kết quả mong muốn thay vì phải gọi trực tiếp tới đối tượng StudentDAO.

Về mặt tính năng, giữa chúng có nhiều tính năng tương đồng và dễ dàng tích hợp với người dùng Eclipse. Nếu như trước đây người dùng PHPUnit cảm thấy yếu thế hơn khi mà PHPUnit không hỗ trợ Mock Object thì giờ đây, từ phiên bản 3 đã hỗ trợ Mock Object (tuy vẫn còn rất hạn chế) và nhiều tính năng khác như Database Testing… Tuy nhiên, người dùng SimpleTest có thể thực sự thấy quá trình Test thực sự “Simple” bởi những tính năng mà nó đem lại.

Resource:

Functional Point Analysis (cont) – II

Trước khi bắt đầu mình sẽ giới thiệu lại quy trình tính toán FP như sau:

  1. Xác định kiểu đo lường (ước lượng cho dự án mới, nâng cấp dự án hay chỉ đánh giá một dự án đã có)
  2. Xác định phạm vi của dự án.
  3. Xác định số lượng Function Points thô (Unadjusted Function Points)
  4. Xác định hệ số cân đối (Value Adjusted Factors).
  5. Xác định số lượng Function Points cân đối (Adjusted Function Points).

Step 1: Xác định kiểu đo lường (Type of Count)

Bước đầu tiên trong phương pháp FPA đó là xác định loại dự án cần ước lượng. Do đó, việc xác định số lượng FPs có thể là việc xác định số lượng FPs của một dự án hoàn toàn mới (Development Project FP Count), số lượng FPs của việc nâng cấp một dự án (Enhancement Project FP Count) hoặc đơn giản chỉ là đánh giá lại một dự án hoàn thành (Application FP Count).

Step 2: Xác định đường biên (boundary) của ứng dụng

- Ứng dụng mà bạn đang xây dựng là ứng dụng độc lập (standalone) hay chỉ là một phần trong một gói (suite) ứng dụng. Nghĩa là nguồn cung cấp dữ liệu để ứng dụng của bạn hoạt động là “nguồn tự cung tự cấp” hay là từ một ứng dụng nào đó. Chẳng hạn như khi một trường đại học muốn gửi thông báo về kết quả của một sinh viên cho gia đình của sinh viên đó, thì nó “hệ thống quản lý điểm thi” phải lấy dữ liệu (tức là thông tin liên lạc của sinh viên đó) từ hệ thống “quản lý sinh viên”.

- Việc xác định đường biên của ứng dụng là rất quan trọng, nó ảnh hưởng trực tiếp lên độ phức tạp của ứng dụng, bởi vì việc phát triển một ứng dụng standalone bao giờ cũng đơn giản hơn các ứng dụng trong các “gói” ứng dụng. “Tiền của tui tui xài!”, dĩ nhiên là cảm thấy “thoải mái” hơn là sử dụng tiền của người khác vì bạn không bị phụ thuộc, và rõ ràng những thay đổi xảy ra đối với cá nhân khác không làm ảnh hưởng lớn đến “việc xài” của bạn. Nó cũng tương tự như trong một dự án, sự trì trệ tại một khâu, một giai đoạn nào đó trong chu trình phát triển sẽ ảnh hưởng lên toàn bộ chu trình. Hay như việc phát triển các phần mềm quản lý nhân viên, quản lý tiền lương riêng lẻ bao giờ cũng đơn giản hơn là việc phát triển một gói giải pháp ERP cho doanh nghiệp rồi! Dĩ nhiên ưu điểm của ERP là tài nguyên được sử dụng hiệu quả hơn song đó cũng chính là vấn đề của nó, làm thế nào để sử dụng hiệu quả nguồn tài nguyên đó!

- Giả sử chúng ta cần xây dựng một ứng dụng “đơn giản” nhằm quản lý điểm cho sinh viên, đồng thời khi có yêu cầu, ứng dụng sẽ in ra kết quả thi và gửi đến gia đình sinh viên đó. Chúng ta giả định rằng, không hề có một ràng buộc nào về một học kỳ phải học những môn học nào, đơn giản, chúng ta có một danh sách các sinh viên, danh sách các môn học và chi tiết điểm của sinh viên cho tất cả các môn học đó (không giống như thực tế lắm vì nếu có một số môn chưa học thì kết quả bằng “zero”… nhưng giả định để cho đơn giản mà).

- Như vậy về mặt CSDL ta sẽ có như sau

  • SinhVien(MaSV, HoTen, MaLop)
  • MonHoc(MaMH, TenMH, SoTinChi)
  • KetQua(MaSV, MaMH, Diem)

- Một lưu ý là thông tin chi tiết của một SinhVien có thể truy xuất từ hệ thống quản lý SinhVien với CSDL như sau (đã lược bỏ một số thông tin)

  • SinhVien(MaSV, HoTen, NgaySinh, DiaChiNha, PhuongXa, QuanHuyen, TinhThanhPho)

Như vậy bạn có thể xác định được boundary của ứng dụng của bạn như sau

Boundary

Step 3a: Xác định FP thô (UFP)

Độ phức tạp của ứng dụng phụ thuộc vào hai yếu tố, đó là mức độ phức tạp của dữ liệu (data) và mức độ phức tạp của việc xử lý (transaction). Do đó, việc xác định UFP là công việc xác định số FPs của dữ liệu (Data Function Points)và số FPs của xử lý (Transaction Function Point).

Data FPs thể hiện khía cạnh dữ liệu trong các chức năng cung cấp cho khách hàng. Nó đặc trưng bởi hai yếu tố ILF (Internal Logical File) và EIF (External Interface File). Việc xác định ILF hay EIF cần được thực hiện trước khi tiến hành chuẩn hóa (normalize) dữ liệu.

- Một ILF là một nhóm các dữ liệu được lưu trữ và bảo trì trong phạm vi hệ thống (bên trong boundary). Thông thường nó là một bảng (table) trong cơ sở dữ liệu của ứng dụng.

- Một EIF cũng là một nhóm dữ liệu nhưng được lưu trữ và bảo trì bởi một ứng dụng khác (bên ngoài boundary). Dĩ nhiên, một EIF này có thể là một ILF của một ứng dụng khác. Thông thường EIF được cung cấp thông qua các services. Chẳng hạn như các services chứng khoán, bảng ngoại tệ, thời tiết…

Transaction FPs thể hiện khía cạnh xử lý của ứng dụng trong các chức năng cung cấp cho khách hàng. Nó đặc trưng bởi ba yếu tố EI (External Inputs), EO (External Outputs), External Inquiries (EQ).

- Một EI là một tiến trình căn bản (element process) trong đó dữ liệu được truyền từ bên ngoài vào bên trong của boundary. Thông thường EI là các thao tác thêm, xóa, cập nhập dữ liệu trong cơ sở dữ liệu

- Một EO là một tiến trình căn bản (element process) trong đó dữ liệu phát sinh (derived data) được truyền từ bên trong ra bên ngoài boundary. Dữ liệu phát sinh đó thường là các dữ liệu được kết hợp với nhau bằng các công thức tính toán như SUM, AVERAGE… Dĩ nhiên, các dữ liệu phát sinh này không xuất hiện trong các ILF hay IEF. Thông thường các EO là bảng báo cáo (reports), các thông báo hay dữ liệu gửi tới các ứng dụng khác.

- Một EQ là một tiến trình căn bản (element process) có hai chiều nhập dữ liệu (input) và xuất dữ liệu (output) nhằm truy xuất dữ liệu từ một hay nhiều ILF/EIF. Trong đó dữ liệu nhập (input) không làm thay đổi dữ liệu của ILF/EIF và dữ liệu xuất không chứa các dòng dữ liệu phát sinh (derived data). Thông thường, EQ là các thao tác tìm kiếm, truy vấn dữ liệu từ các ILF/EIF.

Lưu ý: Tiến trình căn bản (element process) là một xử lý đơn vị đối với người dùng (có nghĩa với họ). Ví dụ, người dùng yêu cầu chức năng thêm một sinh viên với mô tả là một sinh viên có mã số sinh viên, họ tên sinh viên… thì tiến trình căn bản chính là “thêm một sinh viên” chứ không phải là thêm một họ tên, mã số sinh viên…

UFPs figure!

Cách tính UFP

  1. Xác định độ phức tạp cho các ILF và EIF: Gồm việc xác định số lượng ILF và độ phức tạp (Complexity) của mỗi ILF thông qua việc xác định số lượng RETs và DET
    • Xác định số lượng ILF.
    • Xác định độ phức tạp của mỗi ILF bằng cách tính số lượng DETs (Data Element Type) và số lượng RETs (Record Element Type). Trong đó, DETs là các cột (field) dữ liệu, còn RETs là nhóm các cột dữ liệu (có quan hệ phụ thuộc vào nhau, được cập nhập cùng nhau). Để xác định các RETs, thông thường người ta sử dụng phương pháp chuẩn hóa cơ sở dữ liệu.
    • Từ độ phức tạp tính được số FP tương ứng.

  2. Xác định độ phức tạp cho các EI: Căn cứ vào số lượng FTR (File Types Referenced) và DET (Data Element Types) để quyết định độ phức tạp của mỗi EI.
    • Xác định các EI có trong dự án.
    • Tính FTRs và DET cho mỗi EI. Trong đó, mỗi FTR phải là một ILF hoặc một IEF mà EI đó tương tác. Còn DET là mỗi dòng dữ liệu nhập (Data Input Field), thông báo lỗi(error message), thông báo xác nhận (confirm message), buttons, mỗi nhóm radio buttons, check boxes, listbox…
      • Mỗi DATA INPUT FIELD được tính là 1 DET
      • Tất cả các ERROR MESSAGE được tính là 1 DET
      • Tất cả các CONFIRM MESSAGE được tính là 1 DET
      • Mỗi BUTTON được tính là một DET.
      • Mỗi RADIO BUTTON GROUP được tính là 1 DET
      • Mỗi CHECK BOX được tính là 1 DET
      • Mõi LISTBOX, DROP-DOWNLIST… được tính là 1 DET
  3. Xác định độ phức tạp cho các EO: Hoàn toàn tương tự như cách xác định FP cho EI.
    • Xác định các EO có trong dự án.
    • Tính FTRs và DETs cho mỗi EI để suy ra độ phức tạp và số lượng FPs tương ứng. Trong đó số lượng DET được xác định như sau:
      • Mỗi cột dữ liệu đọc được từ ILF, EIF được tính là 1 DET.
      • Mỗi dữ liệu phát sinh (derived data) được tính là 1 DET.
      • Các error message được tính là 1 DET.
      • Các Confirm message được tính là 1 DET.
      • KHÔNG TÍNH tiêu đề (heading) của cột, ngày tháng ngày lập báo cáo. Chỉ tính ngày tháng là một DET nếu nó là dữ liệu có ý nghĩa trong kinh doanh (như lập hóa đơn, ngày đăng ký…

  4. Xác định độ phức tạp cho các EI: Như đã biết, mỗi EI là một tiến trình xử lý gồm hai chiều (thể hiểu như gồm EI và EO). Do đó số lượng FTRs và DETs cuối cùng là sự kết hợp giữa FTRs và DÉTs phía EI và EO. Điều này có nghĩa là nếu cả phía EI và EO cùng sử dụng một FTR thì FTR đó chỉ được tính là MỘT. Tương tự như đối với DET.

Sau khi xác định được độ phức tạp của ta sẽ tính được số lượng FP tương ứng với mỗi EI, EQ, EO.

Cuối cùng ta tính được UFP dựa vào bảng sau. Tạm thời ta chỉ quan tâm tới Total Number of Unadjusted Function Points (Trong bài viết sau sẽ trình bày cách tính Value Adjustment Factor và Total Adjusted Function Points)