- Prison Code Breaker Diary -

=> aka: Nhật Kí Code Tù

Categories

Showing posts with label Tutorial. Show all posts

Let's start unit-test journey using this simple class, in which we want to test whether this class returns all passes or failures.


using System;
using System.Collections.Generic;
using System.Text;

namespace UnitTest
{
    enum CalculatingType
    {
        Addition,
        Subtraction,
        Multiplication,
        Division
    }
    class Calculator
    {
        private List List;
        private CalculatingType cType;

        public Calculator() { }

        public Calculator(List list, CalculatingType type)
        {
            this.List = list;
            this.cType = type;
        }

        public List CList
        {
            get { return this.List; }
            set { this.List = value; }
        }

        public CalculatingType CType
        {
            get { return this.cType; }
            set { this.cType = value; }
        }

        public double GetResult()
        {
            double result = this.List[0];

            for (int i = 1; i < this.List.Count; ++i)
            {
                if (cType == CalculatingType.Addition)
                    result += this.List[i];
                else if (cType == CalculatingType.Subtraction)
                    result -= this.List[i];
                else if (cType == CalculatingType.Multiplication)
                    result *= this.List[i];
                else
                    result /= this.List[i];
            }

            return result;
        }

    }
}

That's it, there have 'Calculator' class containing a list of double values and a enumeration type indicating what kind of computing. Right now, you should have installed NUnit before moving on. Let's create a new class named 'CalculatorTest' to test our created-class 'Calculator'. So what do we want to test? It can be, and should be: + constructors + properties + methods Since this class is quite simple, so testing constructors and properties can be considered alike; in other words, we will test properties and methods of class 'Calculator' In the current project, add a new class named 'CalculatorTest'. Add Reference to NUnit.Framework.Dll, which is located in installed NUnit directory. First of our test code
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace UnitTest
{
    [TestFixture]
    class CalculatorTest
    {
        [Test]
        public void TestCListA()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
            Assert.AreEqual(new List { 1, 2, 3 }, calc.CList);            
        }
    }
}

Build project, then call NUnit from VS, click button 'Run'.
You've got a pass! (list picture below)


So far so good, let's go into some explanation.
Since you've added NUnit Framework, you can add attribute to the classes or methods to indicate you want to test them.
To indicate a class test, [TestFixture] is used before the class declaration, and [Test] is used before methods'.
Simple enough?
Try the next test function to test whether our expected result and actual result are the same

        [Test]
        public void TestCListB()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);            
            Assert.AreEqual(new List { 2, 3, 1 }, calc.CList);
        }

We've got a fail here
UnitTest.CalculatorTest.TestCListB:
  Expected and actual are both  with 3 elements
  Values differ at index [0]
  Expected: 2.0d
  But was:  1.0d

So that means the numbers at index 0 are different. We may understand like both lists containing the same number but arranged in different order, but in facts, it isn't; they're compared one-by-one iterate through index of each list.

Try a different list
        [Test]
        public void TestCListC()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
            Assert.AreEqual(new List { -1, 2, 3 }, calc.CList);
        }

It's certainly a fail because the first value of each list is different.

Let's test the other property, CalculatingType
        [Test]
        public void TestCTypeA()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
            Assert.AreEqual(CalculatingType.Addition, calc.CType);
        }

        [Test]
        public void TestCTypeB()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
            Assert.AreEqual(CalculatingType.Subtraction, calc.CType);
        }
It's easy to see that TestCTypeA() passes and TestCTypeB() fails logically.

Similarly, we will create test function for the GetResult(). Since there're 4 kind of computing, so we will divide into 4 small test functions to check each kind of computing,

        [Test]
        public void TestAddition()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
            Assert.AreEqual(6, calc.GetResult());
        }


        [Test]
        public void TestSubtraction()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Subtraction);                      
            Assert.AreEqual(-4, calc.GetResult());
        }

        [Test]
        public void TestMultiplication()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Multiplication);
            Assert.AreEqual(6, calc.GetResult());
        }

        [Test]
        public void TestDivisionA()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Division);
            Assert.AreEqual(0.1666667, calc.GetResult());
        }

We have passed at function TestAddition(), TestSubtraction(), TestMultiplication(), but failed at function TestDivisionA().
The reason is the floating point not match. Well, it's kinda of trick here.
Luckily that we have first operation 1/2 = 0.5 limited so we can write like

        [Test]
        public void TestDivisionB()
        {
            Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Division);
            Assert.AreEqual( 0.5/3, calc.GetResult());
        }
Good trick! We pass TestDivisionB().
Not happy yet, what if the input for Division containing 0 (zero)?
It is an exception, isn't it?
NUnit provides an attribute to test whether an exception is called out.

        [Test,ExpectedException(typeof(DivideByZeroException))]
        public void TestDivisionC()
        {
            Calculator calc = new Calculator(new List { 1, 2, 0 }, CalculatingType.Division);
            throw new DivideByZeroException();
        }

As you see above, we expect to get an exception type DivideByZeroException, a .NET class.

Software testing is quite a complicated task and consumes a lot of time. Well, this post just demonstrate a very very simple introduction to unit test.
Hope you learn something from this tutorial.

Linux bash shell provides 2 types of test:
+ ( -ot ) : is other than
+ ( -nt ) : is newer than


#!/bin/sh

if [ "$file1" -nt "$file2" ]
then
    echo -e "$file1 is newer than $file2"
else
    echo -e "$file1 is older than $file2"
fi

STATIC LIBRARY (.a)

+ Compile

$ gcc -Wall -c *.c
+ Create library
$ ar -cvq libtest *.o
+ List files in library
$ ar -t libtest.a
+ Linking with library
$ gcc -o executable-name prog.c libtest.a
$ gcc -o executable-name prog.c -L/path/to/library-dir -ltest


Shared Object: DYNAMICALLY LINKED LIBRARY

+ Compile object
$ gcc -Wall -fPIC -c *.c
+ Create shared object
$ gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 -o *.o
+ Move library to destination
$ mv libtest.so.1.0 /path/to/lib-dir
+ Allow naming convention like -ltest
$ ln -sf /path/to/lib-dir/libtest.so.1.0 /path/to/lib-dir/libtest.so
+ Allow run-time binding to work
$ ln -sf /path/to/lib-dir/libtest.so.1.0 /path/to/lib-dir/libtest.so.1
+ Testing executable file dependencies
$ ldd executable-file


Reference: Yo-Linux

Original Topic Discussion => [Cviet]

Relax #1 [ by me ]

Given 3 functions:

int add( int _a, int _b ) { return _a + _b; }
int sub( int _a, int _b ) { return _a - _b; }
int mul( int _a, int _b ) { return _a * _b; }

Implement the following program:
+ Prompt user to input 1 of 4 strings: "add", "sub", "mul" or "end"; otherwise, start program again; "end" to exit.
+ Then, prompt user to input 2 numbers
+ Output result in this form

A [operator] B = [result]

Operator must be one of the following '+', '-' and '*', according to its own function, which means string "add" match add() function ....

Requirement
+ Must use function pointer
+ Call function according to its name, call add() if user prompt "add"....so on.
+ Language to use: C, C++

Demo output

> type 'add', 'sub', 'mul' or 'end': add
 a = 1
 b = 2
 1 + 2 = 3
> type 'add', 'sub', 'mul' or 'end': sub
 a = 6
 b = 4
 6 - 4 = 2
> type 'add', 'sub', 'mul' or 'end': mul
 a = 12
 b = 1
 12 * 1 = 12
> type 'add', 'sub', 'mul' or 'end': end

PROGRAM ENDED ! 


Solution #1 [ by me ]


Code in C as following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE    1024

//
// #struct JFUNC
//
struct JFUNC {
    char *name;                 // function name
    int (*func)(int, int);      // pointer to function
    char sign;                  // sign of function, '+', '-', '*'
};

//
// #function        say()
// #purpose         format output with given params
//
void say( int (*func)(int,int), int _a, int _b, char _ )
{
    printf(" %d %c %d = %d\n", _a, _, _b, func( _a, _b ) );
}

//
// #function        input()
// #purpose         get input from user
//
void input( int *a, int *b ) {
    printf(" a = "); scanf("%d%*c", a);
    printf(" b = "); scanf("%d%*c", b);
}

//
// #function        add(),sub(),mul()
// #purpose         provide regular calculation
//
int add( int _a, int _b ) { return _a + _b; }
int sub( int _a, int _b ) { return _a - _b; }
int mul( int _a, int _b ) { return _a * _b; }
//int div( int _a, int _b ) { return _a / _b; }

/* ENTRY POINT */
int main( )
{
    // init array of 3 structs
    struct JFUNC calc[3] = {
        { "add", add, '+' },
        { "sub", sub, '-' },
        { "mul", mul, '*' }
    };
    int a, b; // input from user
    int idx; // index of struct JFUNC array
    char *key = (char *)malloc( MAX_SIZE * sizeof(char) ); // string to get from user
    do {
   
        printf("> type 'add', 'sub', 'mul' or 'end': " );
        // get input, exactly 4 bytes
        fgets( key, MAX_SIZE, stdin );     

        // iterate through array to get correct function
        for( idx = 0; idx < 3; ++idx ) {
            // if function name is matched
            if( strcmp(calc[idx].name, key) == 0 ) {
                // get input
                input( &a, &b );
                // output
                say( calc[idx].func, a, b, calc[idx].sign );
            }
        }
    // end program if "end" prompted
    } while ( strcmp(key, "end") != 0 );
   
    // free memory
    free( key );
   
    printf(" PROGRAM ENDED!\n");
    // program return
    return 0;
}

Code in C++ as following

#include <iostream>

using namespace std;

//
// #struct JFUNC
//
struct JFUNC {
    string name;                    // function name
    int (*func)(int, int);      // pointer to function
    char sign;                  // sign of function, '+', '-', '*'
};

//
// #function        say()
// #purpose         format output with given params
//
void say( int (*func)(int,int), int _a, int _b, char _ )
{
    cout << " " << _a << " " << _ << " " << _b << " = " << func( _a, _b ) << "\n";
}

//
// #function        input()
// #purpose         get input from user
//
void input( int *a, int *b ) {
    cout << " a = "; cin >> *a;
    cout << " b = "; cin >> *b;
}

//
// #function        add(),sub(),mul()
// #purpose         provide regular calculation
//
int add( int _a, int _b ) { return _a + _b; }
int sub( int _a, int _b ) { return _a - _b; }
int mul( int _a, int _b ) { return _a * _b; }
//int div( int _a, int _b ) { return _a / _b; }

/* ENTRY POINT */
int main( )
{
    // init array of 3 structs
    struct JFUNC calc[3] = {
        { "add", add, '+' },
        { "sub", sub, '-' },
        { "mul", mul, '*' }
    };
    int a, b; // input from user
    int idx; // index of struct JFUNC array
    string key; // string to get from user
    do {
   
        cout << "> type 'add', 'sub', 'mul' or 'end': ";
        // get input, exactly 4 bytes
        cin >> key;

        // iterate through array to get correct function
        for( idx = 0; idx < 3; ++idx ) {
            // if function name is matched
            if( calc[idx].name == key ) {
                // get input
                input( &a, &b );
                // output
                say( calc[idx].func, a, b, calc[idx].sign );
            }
        }
    // end program if "end" prompted
    } while ( key != "end" );
   

    cout << " PROGRAM ENDED!\n";
    // program return
    return 0;
}

Solution #2 [ by tauit_dnmd ]

/*
  UITs:UITstudent.com
  Coder:tauit_dnmd.
*/
#include<iostream>
#include<string>
using namespace std;
typedef int (*MyType)(int,int);

int  add( int _a, int _b ) { return _a + _b; }
int sub( int _a, int _b ) { return _a - _b; }
int mul( int _a, int _b ) { return _a * _b; }

int (*GetFunctionVerSion1(string s,char &oper))(int,int) 
{
        if(s=="add"){oper='+'; return &add;}
        if(s=="sub"){oper='-';return ⊂}
        if(s=="mul"){oper='*'; return &mul;}
}

MyType GetFunctionVerSion2(string s,char &oper)
{
        if(s=="add"){oper='+'; return &add;}
        if(s=="sub"){oper='-';return ⊂}
        if(s=="mul"){oper='*'; return &mul;}
}

int main()
{
    int (*uitstudent)(int,int)=NULL;//define 
    int a,b;
    string myoperator;//operator
    char UITs;
    do
    {
        do
        {
            cout<<"type 'add' 'sub' 'mul' or 'end':"; 
            cin>>myoperator;
            if(myoperator=="add"||myoperator=="sub"||myoperator=="mul"||myoperator=="end") break;
        }while(1);
        if(myoperator!="end")
        {
            uitstudent=GetFunctionVerSion1(myoperator,UITs);//Or uitstudent=GetFunctionVerSion2(myoperator,UITs);
            cout<<"a= ";cin>>a;
            cout<<"b= ";cin>>b;
            cout<<"a "<<UITs<<" b = "<<(*uitstudent)(a,b)<<endl;
        }
    }while(myoperator!="end");
    cout<<"UITs:PROGRAM END!"<<endl;
    return 0;
}  


Solution #3 [ by QuangHoang ]

#include <iostream>
#include <string>
#include <map>
using namespace std;

typedef int (*func)( int, int );

int add( int _a, int _b ) { return _a + _b; }
int sub( int _a, int _b ) { return _a - _b; }
int mul( int _a, int _b ) { return _a * _b; }

map <string, func> fmap;
map <string, func>::iterator it;

void initMap()
{
    fmap["add"] = add;
    fmap["sub"] = sub;
    fmap["mul"] = mul;
}

bool result(string oper)
{
    bool ok = false;
    for ( it=fmap.begin() ; it != fmap.end(); it++ )
        if ( oper == (*it).first ) ok = true;

    if ( !ok ) return false;
   

    int a, b;
    cout << "a = "; cin >> a;
    cout << "b = "; cin >> b;

    cout << a << " " << oper << " " << b << " = " << fmap[oper]( a,b ) << endl;
   
    cin.ignore();
    return true;
}

string label()
{
    string lbl;

    for ( it=fmap.begin() ; it != fmap.end(); it++ )
        lbl += "'" + (*it).first + "', ";

    return lbl;
}

int main()
{
    initMap();
    string oper;

    cout << "> type " << label() << "or 'end': ";
    do
    {
        getline(cin,oper);
        if (oper == "end") break;  

        if (!result(oper))
            cout << "> retype " << label() << "or 'end': ";
        else cout << "> type " << label() << "or 'end': ";

    } while (true);

    cout << "\nPROGRAM ENDED !";
    return 0;
}


Solution #4 [ by rox_rook ]

#include <iostream>
#include <map>
#include <string>


int add( int a, int b ) { return a + b; }
int sub( int a, int b ) { return a - b; }
int mul( int a, int b ) { return a * b; }
int end( int a, int b ) { return 0;     } // dummy func

typedef int( *FUNC )( int , int );

int main()
{
    std::map< std::string, std::pair< char, FUNC > > _func;

    _func[ "add" ] = std::make_pair< char, FUNC >( '+', add );
    _func[ "sub" ] = std::make_pair< char, FUNC >( '-', sub );
    _func[ "mul" ] = std::make_pair< char, FUNC >( '*', mul );
    _func[ "end" ] = std::make_pair< char, FUNC >( ' ', end );

    std::string user_repl;
    int a, b;

    do {
        std::cout << "> type 'add', 'sub', 'mul' or 'end' : ";
        std::cin >> user_repl;
        if( user_repl == "end" )
            break;
        std::cout << "> 'a' 'b' : ";
        std::cin >> a >> b;
        std::cout << a << _func[ user_repl ].first << b << "=" << _func[ user_repl ].second( a, b ) << "\n";
    }
    while( 1 );

    return 0;
}


Evaluation

- Solution #1: My approach follows the traditions of C, calling function by name through a structure, which is mentioned in C-faq under section 20.6 ( Read C-Faq 20.6 )
- Solution #2: It's kinda handy in matching strings.
- Solution #3: mapping, but not really satisfy requirements.
- Solution #4: mapping using value of pair template, it's short, clear and understandable. I think it's the best solution under C++.

It's possible. Yes, it is!

NOTE: this guide is for education purposes only, not promoting for illegal actions

Requirements:
1. Crossover Linux Professional 7.0: get it here: Download

2. Installation package for Ms Office 2007.

How-to:

1. From menu, choose CrossOver -> Install Windows Software. Pick Microsoft Office 2007, locate the setup.exe file, then install it as in Windows.

2. After all installation done, we need to crack it though.
a. Get this file: Proof.XML
b. Replace the old one located under:

/home/[YOUR_USER_NAME]/.cxoffice/MSOffice/drive_c/Program Files/Common Files/Microsoft Shared/OFFICE12/Office Setup Controller/Proof.en
c. From CrossOver menu -> Run a Windows Command, type: regedit
d. Find the key: HKLM\Software\Microsoft\Office\12.0\Registration\DigitalProductID, and delete it.
e. Close all CrossOver-related program.
d. Under main menu: Applications, you can see Windows Application menu, and enjoy !


Enjoy !

These functions are usually used when dealing with binary data: open, read, write, close, seek and binmode.

I've written this perl script to generate a random binary file:

#!/bin/perl -w

use strict;

use constant RANGE => 0xFF;

if( $#ARGV != 1 ) {
    print "Error: no argument input!\n";
    print "Usage: > perl $0 FILE_NAME MAX_BYTES\n";
    print "Example: > perl $0 data.bin 255\n";
    exit;
}

my $file = $ARGV[0];
my $max_bytes = $ARGV[1];

my $cnt = 0;

open FILE,">", $file or die $!;

while( $cnt < $max_bytes ) {
    print FILE chr(int(rand(RANGE)));
    ++$cnt;
}

close FILE;

print "Binary file '$file' ($max_bytes bytes) generated!\n";

binmode() is not in used, so how does it work? Because I generate random value in ASCII so I can easily convert it into its according character, then simply write into file. It does sound weird but it actually works! The case of using binmode() and just print the number, it doesn't write the binary as expected. I don't understand why ???? The next script is to read a binary file and print out the hex code of each character inside.
#!/bin/perl -w

use strict;

if( @ARGV != 2 ) {
    print
     "Error: wrong arguments input!\n",
 "Usage: > perl $0 FILE BYTES\n",
 "Example: > perl $0 data.bin 255\n";
    exit;
}

my $file = $ARGV[0];
my $bytes = $ARGV[1];

open FILE, "<", $file or die $!;
#binmode FILE;

my $cnt = 0;
while( $cnt < $bytes ) {
    read FILE, my $byte, 1;
    print  sprintf("%02X", ord($byte)). " ";
    ++$cnt;
}
close FILE;
print "\n";


I use read() to get each byte then re-format into hex then print().
I don't use binmode() but it still does work well.

So I think I just don't need binmode() even though it's a binary case.

It's really itchy to have menu list cover half of your screen, they're way too biggggg!!!
I've googled to find the solution but it's like impossible @@!
Finally, I got the answer. This is how-to make it better look for you.

Choose a theme to use in order to edit that theme, example, I use 'Is Ora Smooth'.
Then I locate to its settings at: /usr/share/themes/Is Ora Smooth/gtk-2.0/gtkrc
Run gEdit or any text editor under root permission to edit this file.

Add this option into the file:

gtk-icon-sizes = "panel-menu=16,16"

I'm not sure if you want to make it smaller but the size is often like 16, 24 or 32.
Choose the one that best fits for you.
Logout and apply that theme, you'll see how beautiful it is!

Here's the trick, using the -o, and L option we can search for what we need to print out

ps -opid -A

The End!

Oh yes, it took me time to search for this.
Here's the trick:


ps -o"%C" -p #PID

or simplified version

ps -opcpu -p #PID

The End :D

Commonly, it's very hard for beginners to learn a new thing, especially this case, it's PowerShell. However, if you can see through its core, know the basics, and know how to search for helps or reference, it will be getting easier.
It took me about a week to learn the basis and understand the PowerShell concepts.
1. Using MSDN or MS Technet for PowerShell references.
2. Make use of some functions that provide helps.

There are two commands I use: Get-Command and Get-Help.

1. Get-Command: this function shows a list of commands being available at current session.
You can try by just typing: Get-Command, the list will show itself like this:

CommandType     Name                                 Definition                          
-----------     ----                                 ----------                          
Alias           %                                    ForEach-Object                      
Alias           ?                                    Where-Object                        
Function        A:                                   Set-Location A:                     
Alias           ac                                   Add-Content                         
Cmdlet          Add-Computer                         Add-Computer [-DomainName] 
Cmdlet          Add-Content                          Add-Content [-Path]  [-...
Cmdlet          Add-History                          Add-History [[-InputObject] 
Cmdlet          Add-Member                           Add-Member [-MemberType] 
Cmdlet          Add-PSSnapin                         Add-PSSnapin [-Name]  [...
Cmdlet          Add-Type                             Add-Type [-TypeDefinition] 

As you can see, there are 3 properties shown up: CommandType, Name, and Definition.
There are 3 types of commands: Alias, Cmdlet and Function.
+ Cmdlet: these are the core of PowerShell, it is the real command created to use.
+ Alias: these are just the other names of Cmdlets for instant call.
+ Function: these are the already written Cmdlets for instant access when you don't want to re-type the Cmdlet that are long.
Example, list all of commands that are Cmdlets:
PS> Get-Command -CommandType Cmdlet

2. Get-Help: this command provides help about PowerShell Cmdlets and concepts.
Example, if I want to get information about Get-Command, I  type
PS> Get-Help Get-Command

To get examples about the command,

PS> Get-Help Get-Command -examples

To get details about the coomand,

PS> Get-Help Get-Command -detailed

To get full info about the command,

PS> Get-Help Get-Command -full

Hope this post may help someone finding PowerShell a bit easier to learn!

All information about the environment variable is stored in '$env'.
When you want to retrieve info about any variable, you can follow the syntax

$env:<variable_name>

Here's an example how to use it:


PS C:\> $env:windir
C:\Windows

PS C:\> $env:path
C:\Perl\site\bin;C:\Perl\bin;C:\Program Files\ActiveState Perl Dev Kit 8.0\bin;
C:\Program Files\Borland\Delphi7\Bin;C:\Program Files\Borland\Delphi7\Projects\
Bpl\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;c:\Program Files\M
icrosoft SQL Server\90\Tools\binn\;C:\Web\PHP;C:\Web\PHP\ext;C:\Web\MySQL\bin;C
:\Program Files\QuickTime\QTSystem\;C:\GTK\bin;C:\Program Files\Microsoft Visua
l Studio 8\VC\bin;C:\Program Files\Java\jdk1.6.0_18\bin;C:\GTK2-16\bin;C:\Windo
ws\System32\WindowsPowerShell\v1.0\;C:\Program Files\GTK2-Runtime\bin;C:\BC5\BI
N;C:\Program Files\Nmap;C:\Program Files\Common Files\Nero\Lib\

It's a damn cool thing when you want to save something into HTML format.
Windows PowerShell provides this function through [ConvertTo-HTML] Cmdlets.

Example, if I want to save my list of current processes into HTML format

PS > Get-Process | ConvertTo-HTML | Out-File ProcessHTML.html

Another great thing is that it provides the way how you can format the output the HTML file through these 3 arguments: -head, -body, and -title.
Here, another example of formatting the output

$format_head = "<title> PROCESS LIST </title>"
$format_head += "<style>
"
$format_head += "TABLE { border-width:2px;border-style:solid}"
$format_head += "TH {border-width:1px;border-style:solid}"
$format_head += "TD {border-width:2px;border-style:solid}"
$format_head += "</style>"

$format_body = "<center> PROCESS LIST </center>"

Get-Process | ConvertTo-HTML -head $format_head -body $format_body | Out-File processHTML.html

Hiện tại mình đang viết cuốn sách hướng dẫn lập trình Perl cơ bản bằng tiếng Việt và chỉ dành cho những ai hiểu được tiếng Việt :D
Tên sách: Perl - The 1st Step (Hướng dẫn lập trình Perl cơ bản)
Tác giả: Pete H.

Download

(2010-Feb-05)[JaPh] Perl - The 1st Step (PDF - 1.12 MB)
(2010-Feb-06)[JaPh] Perl - The 1st Step (PDF - 1.14 MB)
(2010-Feb-07)[JaPh] Perl - The 1st Step (PDF - 1.21 MB)
(2010-Feb-09)[JaPh] Perl - The 1st Step (PDF - 1.40 MB)
# Changelog - Thông tin cập nhật

• 2009-Mar-15: sách bắt đầu được viết.
• 2009-Nov: chỉnh sửa và đính chính lần 1.
• 2010-Feb: hoàn thiện cơ bản nội dung và format kiểu cách sách.
• 2010-Feb-05: xuất bản trên Internet lần đầu tiên.
• 2010-Feb-06:

  1. cập nhật thông tin perl editor và perl ide.
  2. thêm hình minh họa.
  3. cập nhật link download sách và version.
• 2010-Feb-07:
  1. cập nhật thêm hình minh họa.
  2. thêm mục mới: K. Comment trong perl.
  3. thêm mục mới: L. Chỉ thị Perl - SHEBANG.
  4. đính chính một vài lỗi chính tả.
• 2010-Feb-09:

  1. cập nhật thêm vào Mục Lục và Phụ Lục.
  2. thêm mục link download công cụ.
  3. thêm hướng dẫn cài đặt EPIC để lập trình Perl.
  4. sửa một vài lỗi chính tả.
  5. thay đổi theme cho mã nguồn perl.
  6. thay đổi theme cho các đoạn code ghi chú.

Best Regards,

Language: Perl
Presiquisite: XML::Simple

Assuming we have a xml file like this: data.xml

<?xml version="1.0" encoding="UTF-8"?>
<database>
<user>
<uname>Pete Houston</uname>
<upass>123456</upass>
<email>pete.houston.17187@gmail.com</email>
<id>1</id>
</user>
<user>
<uname>Bach Van Kim</uname>
<upass>987654</upass>
<email>bvkvn06@gmail.com</email>
<id>2</id>
</user>
</database>
We will dump this XML tree using XML::Simple and Dumper package:

#!C:\perl\bin\perl.exe -w
use strict;
use XML::Simple;
use Data::Dumper;

print Dumper( XML::Simple->new()->XMLin("data.xml"));

The result shows:

$VAR1 = {
'user' => {
'1' => {
'email' => 'pete.houston.17187@gmail.com',
'uname' => 'Pete Houston',
'upass' => '123456'
},
'2' => {
'email' => 'bvkvn06@gmail.com',
'uname' => 'Bach Van Kim',
'upass' => '987654'
}
}
};

The method: XML::Simple->new() will create an object to handle XML file, and then input file will be called through method XMLin("filename.xml");
A very simple way!

Here the instruction on how to install Gtk+ for Perl on Windows.
There are two options:

1. Simply download and setup CamelBox:

2. Using ActivePerl:
+ Download and install ActivePerl: https://www.activestate.com/activeperl/downloads/
+ Download and install Gtk+ Environment for Windows: http://cdnetworks-kr-2.dl.sourceforge.net/project/gladewin32/gtk%2B-win32-runtime/2.8.20/gtk-2.8.20-win32-1.exe
+ Open command and type:


ppm repo add http://www.lostmind.de/gtk2-perl/ppm/
ppm install Gtk2

+ Finally, restart your Windows

There are many ways but those two are the best options of all that I prefer.

Have fun!

Under Windows, it's best to use ActiveState Perl.
In order to manage your Perl package, you might want to use either:

1. Command-line approach:


C:\>perl -MCPAN -e shell;


2. Easier management through GUI:

C:\>ppm

PPM is Perl Package Manager provided by ActiveState.

Have fun!

By using the utility netsh, you may find it easily to manage your network. Yes, it's pretty much convenient.

1. Show network information:


netsh interface ip show config


2. Change setting of ip address, mask and gateway

netsh interface ip set address name="Network Name" static ip_address subnet_mask gateway 1


Sample: set Local Area Connection to static address 192.111.215.96, mask = 255.255.255.252, gateway = 192.111.215.1

netsh interface ip set address name="Local Area Connection" static 192.111.215.96 255.255.255.252 192.111.215.1 1


2. Change DNS setting
+ set DNS

netsh interface ip set dns "Network Name" static dns_address

+ add DNS

netsh interface ip add dns "Network Name" dns_address index=2


3. Export IP setting to file:

netsh -c interface dump > C:\setting.txt


4. Import IP setting from file:

netsh -f C:\setting.txt

or

netsh exec C:\setting.txt


5. Using DHCP
+ Simply add 'dhcp' at the end of your command :D

netsh interface ip set address "Local Area Connection" dhcp
netsh interface ip set dns "Local Area Connection" dhcp



Have fun!

Programming .NET is one of the first thing I've learned myself long ago, but only available in Windows Operating System.
Somehow, the Mono Project has made .NET Framework become a cross-platform environment that you can freely programming .NET for Windows, Linux, MacOS...in that system directly. Also, you can write a .NET program for Linux under Windows and vice-versa. It's really a great achievement that Mono Project has reached. I expect that Mono Project will achieve more impressive goals with .NET technology in the future as it develops.
I write this guide as a journal in programming .NET under Linux environment by using Mono Project.
You may take this as a reference for Gtk#.

1 - Documentation and Reference:
Here the list that I read and reference from:
Gtk# Tutorial Page by Mono
Mono Documentation Library (equivalent to MSDN)
Mono: A Developer's Notebook (Edd Dumbill, Niel M. Bornstein) - A great book, worth to buy for two reasons:
+ It's the only book on Mono up to this time.
+ It's written as a developer's journal style, so it's really easy to catch the authors' mind concepts.

2 - Programming Gtk# Journal

Lesson 1: Say Hello
Lesson 2: Hello Gtk# (using Form)
Lesson 3: MonoDevelop IDE vs. manual text coding w/ commands. (to be updated...)


Feel free to comment!
Have fun!

Download Project

We do the same thing with Lesson 1 but this time we use form for better GUI.
This is the source code, self-explained fully-commented.



using System;
using Gtk;

public class Lesson_2
{

public static void Main() {

Application.Init();

// create a window
Window window = new Window("Lesson 2: Say hello with Gtk# Form");
window.Resize(400, 40);

// create a label
Label label = new Label("Hello Gtk# .NET");
// add label to the form
window.Add(label);
// show form and its widgets
window.ShowAll();

Application.Run();
}
}


Build and run, this is result:


Have fun!

Download Project: Lesson 1 - Say Hello Gtk#

First, open MonoDevelop and create a new empty project. Then, add an empty class file into project. Copy this code below to the file:


using System;

public class Lesson_1 {

public static void Main() {
Console.WriteLine("Lesson 1: Hello Gtk#! It's so wonderful!");
}
}

If you already know C#, you, hence, know what it means.

Now click on the menu Build -> Build Solution or F8.
Click menu Run -> Run or Ctrl+F5.
You will have result like this:

The result is shown under the Application Output textbox.

However, if you want to compile a single C# file or a C# project manually, then do this.

Open the terminal:

terminal> mcs -pkg:gtk-sharp-2.0 Main.cs

A file named Main.exe will be generated. In order to run this file you have to use mono utility:

terminal> mono Main.exe

The result will show up exactly how it is while using MonoDevelop.

Have fun!