Lessons Learned in Software Development

Henrik Warne's blog

Here is my list of heuristics and rules of thumb for software development that I have found useful over the years:

Programming bookshelf

Development

1. Start small, then extend. Whether creating a new system, or adding a feature to an existing system, I always start by making a very simple version with almost none of the required functionality. Then I extend the solution step by step, until it does what it is supposed to. I have never been able to plan everything out in detail from the beginning. Instead, I learn as I go along, and this newly discovered information gets used in the solution.

I like this quote from John Gall:  “A complex system that works is invariably found to have evolved from a simple system that worked.”

View original post 1 428 more words

YAML

[From wikipedia…]

Syntax

A compact cheat sheet (actually written in YAML) as well as a full specification are available at the YAML web site. The following is a synopsis of the basic elements.

  • YAML streams are encoded using the set of printable Unicode characters, either in UTF-8 or UTF-16.
  • Whitespace indentation is used to denote structure; however tab characters are never allowed as indentation.
  • Comments begin with the number sign ( # ), can start anywhere on a line and continue until the end of the line. Comments must be separated from other tokens by white space characters.[7]Unless they appear inside of a string, then they are number ( # ) sign literals.
  • List members are denoted by a leading hyphen ( - ) with one member per line, or enclosed in square brackets ( [ ] ) and separated by comma space ( ,   ).
  • Associative arrays are represented using the colon space ( :   ) in the form key: value, either one per line or enclosed in curly braces ( {   } ) and separated by comma space ( ,   ).
    • An associative array key may be prefixed with a question mark ( ? ) to allow for liberal multi-word keys to be represented unambiguously.
  • Strings (scalars) are ordinarily unquoted, but may be enclosed in double-quotes ( ” ), or single-quotes ( ‘ ).
    • Within double-quotes, special characters may be represented with C-style escape sequences starting with a backslash ( \ ). According to the documentation the only octal escape supported is .
  • Block scalars are delimited with indentation with optional modifiers to preserve ( | ) or fold ( > ) newlines.
  • Multiple documents within a single stream are separated by three hyphens ( --- ).
    • three periods ( ... ) optionally end a file within a stream.
  • Repeated nodes are initially denoted by an ampersand ( & ) and thereafter referenced with an asterisk ( * ).
  • Nodes may be labeled with a type or tag using the exclamation point ( !! ) followed by a string, which can be expanded into a URI.
  • YAML documents in a stream may be preceded by directives composed of a percent sign ( % ) followed by a name and space delimited parameters. Two directives are defined in YAML 1.1:
    • The %YAML directive is used to identify the version of YAML in a given document.
    • The %TAG directive is used as a shortcut for URI prefixes. These shortcuts may then be used in node type tags.

YAML requires that colons and commas used as list separators be followed by a space so that scalar values containing embedded punctuation (such as 5,280 or http://www.wikipedia.org) can generally be represented without needing to be enclosed in quotes.

Two additional sigil characters are reserved in YAML for possible future standardisation: the at sign ( @ ) and accent grave ( ` ).

 

[Thủ thuật] Đặt password cho thư mục trong windows 7 – How to lock a folder in windows 7

Thủ thuật sau đây sẽ giúp bạn khóa một thư mục trên máy tính bằng cách đặt mật khẩu cho thư mục đó, mà không cần phải dùng đến một công cụ của hãng thứ 3 nào khác.

Bước 1:

Tạo một file text (.txt) với nội dung như sau:

cls
@ECHO OFF
title Folder vuonghienuit
if EXIST “Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}” goto UNLOCK
if NOT EXIST vuonghienuit goto MDLOCKER
:CONFIRM
echo Are you sure u want to Lock the folder(Y/N)
set/p “cho=>”
if %cho%==Y goto LOCK
if %cho%==y goto LOCK
if %cho%==n goto END
if %cho%==N goto END
echo Invalid choice.
goto CONFIRM
:LOCK
ren vuonghienuit “Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}”
attrib +h +s “Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}”
echo Folder locked
goto End
:UNLOCK
echo Enter password to Unlock folder
set/p “pass=>”
if NOT %pass%==type your password here goto FAIL
attrib -h -s “Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}”
ren “Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}” vuonghienuit
echo Folder Unlocked successfully
goto End
:FAIL
echo Invalid password
goto end
:MDLOCKER
md vuonghienuit
echo vuonghienuit created successfully
goto End
:End

Đặt password cho thư mục bằng cách thay đổi dòng này:

if NOT %pass%==type your password here goto FAIL

Ví dụ ở đây tôi đổi thành vuonghienuit, sẽ là

if NOT %pass%==vuonghienuit goto FAIL

Đặt cho nó một cái tên nào đó, ví dụ ở đây tôi đặt là locker.txt và lưu lại

Bước 2: 

Lưu file này lại với phần mở rộng là .bat

(Để lưu, click File –> Save As –> sửa tên lại thành locker.bat, chọn phần bên dưới là All Files, như hình):

hướng dẫn đổi tên file

Bước 3:

Chạy file locker.bat vừa có.

Mặc định lần chạy đầu tiên chương trình sẽ tự động tạo thư mục cho bạn.

Sau khi tạo được thư mục, click locker.bat lần nữa, chương trình sẽ hỏi bạn có muốn lock thư mục đó không, gõ Y để khóa.

Gõ Y để lock folder

Gõ Y để lock folder

Lúc này thư mục đã bị ẩn đi.

Sau này khi muốn mở thư mục bạn phải chạy file locker.bat và gõ đúng password.

Bạn phải gõ đúng password đã đặt ở trên

Bạn phải gõ đúng password đã đặt ở trên

Chúc các bạn thành công!..🙂

Nguồn: http://social.microsoft.com

Phân đoạn bảng trong SQL Server (Table partitioning in SQL Server)

<Lưu lại, cần dùng sau này>

<Nguồn: http://www.sqlviet.com/blog/table-partitioning-trong-sql-server#more-2377>

Table partitioning là kỹ thuật phân chia bảng thành từng đoạn nhằm quản lý hiệu quả cơ sở dữ liệu với dung lượng lớn. Đây là tính năng mới được đưa vào SQL Server 2005 và tiếp tục được tăng cường ở phiên bản 2008. Đối với các ứng dụng truy cập từ bên ngoài, bảng (table) vẫn là một bảng duy nhất, chỉ có cấu trúc vật lý của nó là khác so với các bảng không phân đoạn.
Bảng được phân đoạn dựa vào giá trị một trường của nó (trường được chọn gọi là partition key). Ví dụ bạn có dữ liệu về các giao dịch bán hàng chứa trong bảng BanHang, bạn có thể phân đoạn theo năm của trường NgayGiaoDich (ngày giao dịch): các giao dịch xảy ra trong năm 2009 được nằm trong một đoạn riêng, tương tự với các giao dịch của năm 2010… Kỹ thuật này làm tăng khả năng mở rộng của SQL Server lên rất nhiều, và giúp cho việc quản trị các cơ sở dữ liệu lớn trở nên dễ dàng hơn. Thử hình dung với một bảng dữ liệu chứa vài trăm triệu bản ghi thường xuyên được cập nhật, các tác vụ như backup/restore, hoặc create/rebuild index đều rất tốn kém thời gian. Việc truy vấn hoặc sửa đổi dữ liệu cũng rất vất vả. Table partitioning nhằm giải quyết các trở ngại đó, nó có các ưu điểm chính sau:

1. Tiện lợi về quản trị

– Bạn có thể backup/restore một đoạn mà không ảnh hưởng đến các đoạn còn lại: ví dụ tại thời điểm năm 2010 thì các đoạn chứa dữ liệu của 2009 và các năm trước không còn tiếp nhận dữ liệu mới nữa, bạn không cần phải thường xuyên backup các đoạn này và chỉ cần backup đoạn 2010.

– Bạn cũng có thể REBUILD lại index trên từng đoạn (những đoạn cần phải REBUILD do có nhiều thao tác xóa, sửa) thay vì trên toàn bộ bảng.

– Nó cũng cho phép nhanh chóng loại bỏ dữ liệu nguyên một đoạn ra khỏi bảng thay vì phải dùng lệnh DELETE (thao tác này gọi là SWITCH-OUT). Tương tự nó cũng cho phép “nạp” dữ liệu từ một bảng khác vào thành một đoạn mới (SWITCH-IN). Tính năng này rất có giá trị đối với các ứng dụng ETL và Datawarehouse.
Ví dụ bạn cần import dữ liệu của năm 2008, bạn có thể import vào một bảng riêng và sau đó switch-in bảng này vào bảng chính một cách tức thì. Trước khi có partitioning, bạn phải dùng lệnh INSERT để chuyển dữ liệu từ bảng riêng vào bảng chính. Quá trình này mất nhiều thời gian hơn và trong suốt quá trình đó bảng bị khóa và không thể truy cập được.

2. Cải tiến về hiệu năng

– Khi một câu lệnh chỉ cần lấy dữ liệu ở một đoạn nào đó thì hệ thống chỉ cần truy nhập vào đoạn đó và bỏ qua các đoạn còn lại (tính năng này gọi là partition elimination)
– Khi các đoạn dữ liệu được lưu trữ ở các ổ cứng khác nhau sẽ làm giảm tranh chấp vào/ra giữa các câu lệnh. Ví dụ hai câu lệnh SELECT và UPDATE hoạt động trên cùng một bảng nhưng ở hai đoạn khác nhau có thể thực hiện hoàn toàn song song với nhau.

Việc phân đoạn bảng dựa trên hai khái niệm mới sau đây:

· Partition function: qui định giá trị biên cho các đoạn. Hệ thống dựa vào hàm này để xác định đoạn mà mỗi bản ghi thuộc vào.

· Partition scheme: ánh xạ các đoạn khai báo trong partition function vào các filegroup (mỗi đoạn được lưu trữ tại một filegroup).

Dưới đây tôi sẽ đi qua từng bước thiết lập việc phân đoạn thông qua một ví dụ cụ thể.
Bạn có bảng BanHang gồm các cột BangHang_ID, NgayGiaoDich, MaSP, SoLuong, ThanhTien. Bạn muốn phân đoạn bảng theo từng năm của NgayGiaoDich: để cho đơn giản, giả sử bạn muốn lưu các giao dịch của năm 2009 trở về trước vào một đoạn, trong năm 2010 vào một đoạn, và từ 2011 trở đi vào một đoạn (về sau bạn vẫn luôn luôn có thể sửa đổi để giành riêng một đoạn cho 2011 và bổ sung các đoạn mới cho 2012, 2013…). Như vậy với cấu hình ở trên, bảng sẽ có 3 đoạn: 2009 trở về trước, 2010, và 2011 trở về sau. Do đó bạn cũng cần 3 filegroup.

Bước 1: Tạo database và filegroup

CREATE DATABASE PartTest
GO
USE PartTest
GO
-- tạo filegroup
ALTER DATABASE PartTest ADD FILEGROUP FG2009AndBefore 
ALTER DATABASE PartTest ADD FILEGROUP FG2010 
ALTER DATABASE PartTest ADD FILEGROUP FG2011AndAfter

– thêm data file vào mỗi filegroup

ALTER DATABASE PartTest ADD FILE (NAME = N'FY2009AndBefore', FILENAME = N'D:\DATA\PartTest\FY2009AndBefore.ndf') TO FILEGROUP FG2009AndBefore 
ALTER DATABASE PartTest ADD FILE (NAME = N'FY2010', FILENAME = N'D:\DATA\PartTest\FY2010.ndf') TO FILEGROUP FG2010 
ALTER DATABASE PartTest ADD FILE (NAME = N'FY2011AndAfter', FILENAME = N'D:\DATA\PartTest\FY201AndAfter.ndf') TO FILEGROUP FG2011AndAfter

Bước 2: Tạo partition function và partition scheme

USE PartTest
GO
CREATE PARTITION FUNCTION PFunc_NGD(DATETIME) AS RANGE RIGHT FOR VALUES ('2010-01-01', '2011-01-01') 
GO 
CREATE PARTITION SCHEME PScheme_NGD AS PARTITION PFunc_NGD TO (FG2009AndBefore, FG2010, FG2011AndAfter)

Hàm partition function có tên PFunc_NGD định nghĩa giá trị biên cho các đoạn, là ngày đầu tiên của năm 2010 và ngày đầu tiên của 2011. Giống như khi bạn cắt một sợi dây, chỉ cần 2 nhát cắt để chia sợi dây làm 3 đoạn, ở đây cũng chỉ có 2 giá trị biên. Do vậy dải giá trị của các đoạn sẽ như sau:

Đoạn 1: từ trước đến 2009-12-31 23:59:59

Đoạn 2: 2010-01-01 00:00:00 đến 2010-12-31 23:59:59

Đoạn 3: 2011-01-01 00:00:00 về sau

Sau đó partition scheme PScheme_NGD dùng hàm PFunc_NGD để “gắn” các đoạn vào từng filegroup. Như vậy đoạn 1 sẽ đến FG2009AndBefore, đoạn 2 đến FG2010 và đoạn 3 đến FG2011AndAfter.

Lưu ý là partition function không giống với các user-defined function. Trong Management Studio, bạn thấy partition function và partition scheme ở mục Database/Storage.

Một lưu ý nữa là một partition function có thể được dùng cho nhiều partition scheme, và cả hai là các đối tượng chung trong database chứ không gắn liền với một bảng cụ thể. Khi định nghĩa bảng (xem bước 4) bạn cần chỉ định dùng partition scheme nào.

Bước 4: Tạo bảng dùng partition scheme

USE PartTest
GO
CREATE TABLE dbo.BanHang(
BangHang_ID INT IDENTITY,
NgayGiaoDich DATETIME,
MaSP INT,
SoLuong INT,
ThanhTien INT
) ON PScheme_NGD(NgayGiaoDich)
GO
CREATE CLUSTERED INDEX CI_BanHang_NGD ON dbo.BanHang(NgayGiaoDich) ON PScheme_NGD(NgayGiaoDich)

Mệnh đề “ON PScheme_NGD(NgayGiaoDich)” trong hai lệnh tạo bảng và tạo index ở trên chỉ định bảng BanHang và index CI_BanHang_NGD được tạo trên partition scheme PScheme_NGD, có nghĩa là để cho nó quản lý việc phân bổ dữ liệu. Vậy là bảng BanHang đã được phân đoạn. Bạn có thể kiểm tra xem dữ liệu được ghi vào đoạn nào:

SELECT $PARTITION.PFunc_NGD('2008-07-24')
SELECT $PARTITION.PFunc_NGD('2009-12-31')
SELECT $PARTITION.PFunc_NGD('2010-01-01')
SELECT $PARTITION.PFunc_NGD('2010-11-25')
SELECT $PARTITION.PFunc_NGD('2011-03-16')

Ví dụ về Hệ chuyên gia (các hệ cơ sở tri thức) – Expert System (Knowledge Base Systems)

1. Tóm tắt lý thuyết:

Khái niệm:

Hệ chuyên gia là một loại hệ cơ sở tri thức được thiết kế cho một lĩnh vực ứng dụng cụ thể. Ví dụ: Hệ chuyên gia về chẩn đoán bệnh trong y khoa, hệ chuyên gia chẩn đoán hỏng hóc máy tính và cung cấp các ý kiến dựa trên kinh nghiệm của chuyên gia con người đã được đưa vào hệ chuyên gia.

Các hệ chuyên gia làm việc như một chuyên gia thực thụ

Hệ chuyên gia được thiết kế để giải quyết các vấn đề phức tạp về lý luận tri thức.

Thành phần:

Một hệ chuyên gia gồm có các thành phần sau:

 Ví dụ HCG

Trong đó 2 thành phần quan trọng nhất là Cơ sở tri thứcđộng cơ suy diễn.

–      Cơ sở tri thức là nơi lưu trữ biểu diễn các tri thức mà hệ đảm nhận, làm cơ sở cho các hoạt động của hệ. Cơ sở tri thức bao gồm các sự kiện và các luật.

–      Động cơ suy diễn: là quá trình trong hệ chuyên gia cho phép khớp các sự kiện trong vùng nhớ làm việc với các tri thức về các lĩnh vực trong cơ sở tri thức, để rút ra các kết luận về các vấn đề đang giải quyết.

Ngoài ra còn có các bộ xử lý ngôn ngữ tự nhiên, bộ giải thích WHY-HOW, vùng nhớ làm việc, bộ tiếp nhận tri thức và người chuyên gia (kĩ sư tri thức).

2. Một ví dụ hệ chuyên gia: hệ nhận dạng động vật – Animal Identification

Hệ nhận dạng một số động vật trong bài này sử dụng cơ sở tri thức người dùng dựa trên các sự kiện người dùng đưa vào thông qua các phiên hỏi đáp. Hệ chuyên gia sẽ sử dụng một động cơ suy diễn thích hợp để kết hợp các sự kiện người dùng đưa vào đó với các luật đã được xây dựng sẵn để tìm được mục tiêu thích hợp.

Kiến trúc chương trình:

Kiến trúc chương trình

Một phiên làm việc gồm:

–      Mục tiêu cần giải quyết

–      Danh sách các câu hỏi cần được trả lời cho đến khi vấn đề được giải quyết.

–      Phản hồi từ người dùng.

Phản hồi từ người dùng là sự lựa chọn câu trả lời có hoặc không có sự kiện đó cho câu hỏi đang được hỏi

Mô hình suy diễn

Cách lựa chọn mục tiêu:

Hệ nhận dạng động vật đưa ra kết luận đó là động vật gì dựa trên các đặc điểm (thuộc tính) nổi bật của nó. (Các thuộc tính này được xây dựng sẵn trong phần cơ sở tri thức).

Đối với mỗi thuộc tính, hệ sẽ ghi nhận giá trị có hay không có thuộc tính đó thông qua câu trả lời của người dùng, và đưa ra kết luận về con vật đó dựa trên các đặc tính mà nó có.

Hệ sử dụng suy diễn tiến dựa trên các luật để tìm được đáp án.

Biểu diễn tri thức:

Tri thức của hệ nhận dạng động vật gồm tập các sự kiện (gồm các đặc điểm của động vật), tập luật và các câu hỏi cho người dùng.

  • Các sự kiện được biểu diễn trong file text Su_kien.txt gồm 2 phần Attribute và Value. 

              Ví dụ cho các sự kiện:”6.Da nó không có vảy”; “7.Nó biết nhảy”; “8.Nó có vảy tròn”; “9.Nó không có vảy tròn”…

  • Các luật được biểu diễn trong file Luat.txt gồm 2 mệnh đề mỗi luật, dạng luật dẫn If….then.

               Ví dụ, con vật đó là tê giác nếu nó thỏa mãn các sự kiện: 1,13,16,23,26,51; tương ứng với các sự kiện: nó là động vật máu nóng (1),                    nó là động vật uống sữa (13), nó không ăn thịt (16), nó có móng guốc (23), nó không có móng guốc (26) và móng có lớp mạ bảo vệ (51).

  • Các câu hỏi cho người dùng để lấy các sự kiện được xây dựng sẵn dựa trên các file Su_kien.txt.

Cách thức suy diễn:

Hoạt động của hệ là đi chứng minh đó là một con vật nào đó dựa trên cơ sở tri thức và sự lựa chọn trả lời có hay không một thuộc tính nào đó của người dùng.

Cơ sở tri thức:

Thu thập tri thức về một số đặc điểm riêng để phân loại động vật dựa trên phân nhóm động vật trong khoa học sinh học.

Ví dụ các nhóm động vật máu nóng, động vật máu lạnh. Trong động vật máu nóng thì có động vật ăn thịt và động vật ăn cỏ, trong động vật ăn cỏ thì lại chia thành động vật có móng guốc và không có móng guốc, vân vân.. 

Ta có biểu đồ cơ sở tri thức như sau:

Sơ đồ biểu diễn tri thức

Demo:

demo giao diện

Click nút “Bắt đầu” để bắt đầu phiên làm việc và nhấn chọn các câu trả lời, nhấn OK cho đến khi tìm được luật phù hợp với các dữ liệu người dùng nhập.

Ở đây sau khi ta nhập lần lượt câu trả lời cho các câu hỏi thì hệ tìm ra được câu trả lời:

Câu trả lời là con ngựa hoặc ngựa vằn, kèm theo sự giải thích bên dưới, và hình ảnh về con vật đó, khi click nút “Xem hình”.

ngựa vằn

Trên chỉ là một demo nhỏ thôi..😀

Chúc các bạn học tốt!

Về Đồ thị khái niệm – Conceptual Graph

Đồ thị khái niệm (Conceptual Graph – CG) là một hình thức biểu diễn tri thức. Trong báo cáo đầu tiên công bố về CG, John.F.Sowa đã sử dụng chúng để biểu diễn các lược đồ khái niệm được sử dụng trong các hệ thống cơ sở dữ liệu. Các sách đầu tiên về CG (Sowa 1984) áp dụng một loạt các chủ đề trong trí thông minh nhân tạo , khoa học máy tính , và khoa học nhận thức .

Từ năm 1984, mô hình đã được phát triển theo ba hướng chính

 

Một giao diện đồ họa cho logic bậc nhất

Trong phương pháp này , một công thức trong logic bậc nhất (vị từ tính toán) được biểu diễn bởi một đồ thị có gán nhãn .
Một ký hiệu tuyến tính, được gọi là Conceptual Graph Interchange Format (CGIF) , đã được chuẩn hóa  trong chuẩn ISO cho Common Logic.

Sơ đồ bên dưới là một ví dụ về các hình thức hiển thị cho một đồ thị khái niệm .

 

Mỗi hộp được gọi là một nút khái niệm, và một hình oval được gọi là một nút quan hệ . Trong CGIF, CG này sẽ được biểu diễn bởi câu sau đây :

[Cat Elsie] [Sitting *x] [Mat *y] (agent ?x Elsie) (location ?x ?y)

 

Trong CGIF, các dấu ngoặc vuông kèm theo thông tin bên trong các nút khái niệm , và dấu ngoặc đơn kèm theo thông tin bên trong các nút quan hệ . Các chữ x và y, được gọi là nhãn coreference , biểu diễn cách các nút khái niệm và các nút quan hệ được nối với nhau như thế nào . Trong Common Interchange Format Logic ( CLIF ) , những kí tự được ánh xạ vào các biến , như trong các câu sau đây :

(exists ((x Sitting) (y Mat)) (and (Cat Elsie) (agent x Elsie) (location x y)))

 

Như ví dụ này cho thấy , các dấu sao trên các nhãn coreference * x * y trong CGIF ánh xạ đến các biến lượng từ tồn tại trong CLIF, và các dấu chấm hỏi trên ?y ?x ánh xạ đến các biến ràng buộc trong CLIF . Một lượng từ với mọi, biểu diễn bởi @every* z trong CGIF , sẽ được biểu diễn là forall ( z) trong CLIF.
Sự suy luận có thể được thực hiện bằng cách chuyển đổi  đồ thị thành các công thức logic , sau đó áp dụng một động cơ suy luận logic .