Showing posts with label Phalanger. Show all posts
Showing posts with label Phalanger. Show all posts

Sunday, October 27, 2013

Arrays and Indexers in Phalanger



Today's post is about Arrays and Indexers in Phalanger (PHP). Here below you will find a very easy to follow program, that demonstrate arrays and indexer, by implementing some simple tasks that will make you grasp the idea of those 2 features real quick. The main goal of this post, is not really teaching arrays because, come on, you probably already know "all" about them, in fact, it is more to show you how you do that in Phalanger (PHP), in this case, compared to all other 22 languages on future posts, which essentially, is the real aim behind this blog.

This is the first post of a "dynamic" language implemented for the DLR. You will notice that the code structure its slightly different from previous posts. Besides that, because Phalanger is PHP, it is definitely better to use PHP's array type instead of System\Array, implemented in Phalanger as PhpArray which at the end, stores the data as a Dictionary<object,object>.

By the way, if you missed my most recent post, "New Series - Arrays and Indexers", check it out. It has more details about the following program, and a bunch of definitions for the concepts used on this, and the following, posts. Or you can check my previous posts about arrays in C# and C++ just to compare.

I encourage you to copy the code below and try it yourself, normally, all programs you find in this blog are source code complete, just paste it on your IDE and run it.

There is room for improvement of the code, using generics is one example, but Generics, Collections, lambdas, etc. will have their own "series" of posts.


<?php
namespace PhpArrays 
{    
    use System as S;
    use System\Console;
    use System\Random;
    use System\Text as T;
    
    class Program
    {
        static function Main()
        {            
            /* 
             * An array in PHP is actually an ordered map.
             * implements arrays as Phpp.Runtime.PhpArray class 
             * that internally implements a Dictionary<object,object>.
            */
            
            // Single-dimensional Array(s)  
            self::printTitle("Reverse Array Elements");
            
            // Declare and Initialize Array of Chars  
            $letters = array();  
            $letters[0] = "A";  
            $letters[1] = "E";  
            $letters[2] = "I";  
            $letters[3] = "O";  
            $letters[4] = "U"; 
            
            //print_r($letters);
            self::printArray($letters);
            $inverse_letters = self::reverseChar($letters);  
            self::printArray($inverse_letters);  
            
            self::printTitle("Sort Integer Array Elements");  
            
            // Declare and Initialize Array of Integers   
            $numbers = array ( 10, 8, 3, 1, 5 );  
            self::printArray($numbers);  
            $ordered_numbers = self::bubbleSort($numbers);  
            self::printArray($ordered_numbers);  
            
            self::printTitle("Sort String Array Elements");  
            
            // Declare and Initialize and Array of Strings  
            $names = array (                       
                    "Damian",   
                    "Rogelio",  
                    "Carlos",   
                    "Luis",                       
                    "Daniel"  
                );  
            self::printArray($names);  
            $ordered_names = self::bubbleSort($names);  
            self::printArray($ordered_names);  
            
            // Multi-dimensional Array (Matrix row,column)  
            // in PHP they are the same as Jagged Arrays or "array of arrays"
            
            self::printTitle("Transpose Matrix");  
            
            /* Matrix row=2,col=3 
             * A =  [6  4 24] 
             *      [1 -9  8] 
             */  
            $matrix = array ( array ( 6, 4, 24 ),   
                              array ( 1, -9, 8 ));  
            self::printMatrix($matrix);  
            $transposed_matrix = self::transposeMatrix($matrix);  
            self::printMatrix($transposed_matrix);  
            
            // Jagged Array (Array-of-Arrays)         
            
            self::printTitle("Upper Case Random Array & Graph Number of Elements");  
            
            /*              
             * Creating an array of string arrays using the String.Split method 
             * instead of initializing it manually as follows: 
             *  
             * $text = array (  
             *      array ( "word1", "word2", "wordN" ),  
             *      array ( "word1", "word2", "wordM" ),  
             *      ... 
             *      ); 
             *  
             * Text extract from: "El ingenioso hidalgo don Quijote de la Mancha" 
             *  
             */  
            // using php function explode (split also works)
            $text = array (   
            \explode(" ", "Hoy es el día más hermoso de nuestra vida, querido Sancho;"),  
            \explode(" ", "los obstáculos más grandes, nuestras propias indecisiones;"),  
            \explode(" ", "nuestro enemigo más fuerte, miedo al poderoso y nosotros mismos;"),  
            \explode(" ", "la cosa más fácil, equivocarnos;"),
            \explode(" ", "la más destructiva, la mentira y el egoísmo;"),
            \explode(" ", "la peor derrota, el desaliento;"),
            \explode(" ", "los defectos más peligrosos, la soberbia y el rencor;"),
            \explode(" ", "las sensaciones más gratas, la buena conciencia...")
            );          
            //print_r ($text);
            self::printJaggedArray($text);  
            $text = self::upperCaseRandomArray($text);  // param not by reference
            self::printJaggedArray($text);  
            self::graphJaggedArray($text);  
            
            // Array Exceptions  
            
            self::printTitle("Common Array Exceptions");  
            
            self::printCommonArrayExceptions(NULL);  
            self::printCommonArrayExceptions($text);  
            
            // Accessing Class Array Elements through Indexer  
            
            self::printTitle("Alphabets");  
            
            $vowels = new Alphabet(5);  
            $vowels[0] = 'a';  
            $vowels[1] = 'e';  
            $vowels[2] = 'i';  
            $vowels[3] = 'o';  
            $vowels[4] = 'u';  
            
            //print_r ($vowels);
            
            echo "\nVowels = {" 
                . \implode(",", array($vowels[0], $vowels[1], $vowels[2], $vowels[3], $vowels[4])) 
                . "}\n";                  
            
            $en = new Alphabet("abcdefghijklmnopqrstuvwxyz");  
            echo "English Alphabet = {{$en}}\n";  
  
            echo "Alphabet Extract en[9..19] = {"
                . new Alphabet($en->slice(9, 10))  
                . "}\n";
            
            $word1 = \implode("", array ($en[6], $en[14], $en[14], $en[3]));  
            $word2 = \implode("", array ($en[1], $en[24], $en[4]));  
            $word3 = \implode("", array ($en[4], $en[21], $en[4], $en[17],  
                                         $en[24], $en[14], $en[13], $en[4]));  
  
            echo "\n$word1 $word2, $word3!\n";
  
            \fgets(STDIN);

            return 0;
        }
        
        static function reverseChar($arr)
        {              
            $reversed = array();  
            for ($i = 0, $j = \count($arr) - 1; $j >= 0; $i++, $j--)  
            {
                $reversed[$i] = $arr[$j]; 
            }
            return $reversed;  
            // or: return \array_reverse($arr);
        }  
        
        static function bubbleSort($arr)  
        {  
            $swap = 0;  
            for ($i = \count($arr) - 1; $i > 0; $i--)  
            {  
                for ($j = 0; $j < $i; $j++)  
                {  
                    // if ($arr[$j][0] > $arr[$j + 1][0])  
                    if (\is_numeric($arr[$j]) ? 
                        $arr[$j] > $arr[$j + 1] : 
                        $arr[$j][0] > $arr[$j + 1][0])  
                    {  
                        $swap = $arr[$j];  
                        $arr[$j] = $arr[$j + 1];  
                        $arr[$j + 1] = $swap;  
                    }  
                }  
            }  
            return $arr;  
        }  
                                    
        static function transposeMatrix($m)  
        {  
            /* Transposing a Matrix 2,3  
             *  
             * A =  [6  4 24]T [ 6  1]  
             *      [1 -9  8]  [ 4 -9] 
             *                 [24  8] 
             */
            $transposed = array();  
            for ($i = 0; $i < \count($m); $i++)  
            {  
                for ($j = 0; $j < \count($m[0]); $j++)  
                {  
                    $transposed[$j][$i] = $m[$i][$j];                  
                }  
            }  
            return $transposed;  
        }  
        
        static function upperCaseRandomArray($arr)  
        {  
            $r = new Random();  
            $i = $r->Next(0, \count($arr) - 1);  
            for ($j = 0; $j < \count($arr[$i]); $j++)  
            {
                $arr[$i][$j] = \strtoupper($arr[$i][$j]);  
            }
            return $arr;
        }  
        
        static function printArray($arr)  
        {  
            echo "\nPrint Array Content " . $arr->GetType()->Name . "\n";
            
            for ($i = 0; $i < \count($arr); $i++)  
            {
                Console::WriteLine(" array [{0,2}] = {1,2} ", $i, $arr[$i]);          
            }
        }  
        
        static function printMatrix($m)  
        {  
            echo "\nPrint Matrix Content " . $m->GetType()->Name 
            . "[" . \count($m) . "," . \count($m[0]) . "]\n";        
            
            for ($i = 0; $i < \count($m); $i++)  
            {
                for ($j = 0; $j < \count($m[0]); $j++)  
                {
                    Console::WriteLine(" array [{0,2},{1,2}] = {2,2} ", $i, $j, $m[$i][$j]);  
                }
            }
        }  
        
        static function graphJaggedArray($arr)  
        {  
            /* When using Arrays, we can use foreach instead of for:  
             *  
             * for (int i = 0; i <= arr.Length - 1; i++) 
             *   for (int j = 0; j <= arr.Length - 1; j++)                 
             *  
             */  
            echo "\nPrint Text Content " . $arr->GetType()->Name . "\n";  
            $lineCount = 1;  
            foreach ($arr as $s)  
            {  
                Console::Write("Line{0,2}|", $lineCount);  
                foreach ($s as $w)  
                {  
                    Console::Write("{0,3}", '*');  
                }  
                echo " (" . \count($s) . ")\n";  
                $lineCount++;  
            }  
        }  
        
        static function printJaggedArray($arr)  
        {          
            echo "\nPrint Jagged Array Content " . $arr->GetType()->Name . "\n";  
            for ($i = 0; $i < \count($arr); $i++)  
            {  
                $line = new T\StringBuilder();  
                for ($j = 0; $j < \count($arr[$i]); $j++)
                {
                    $line->Append(" " . $arr[$i][$j]);  
                }
                if ($line->ToString() == \strtoupper($line->ToString()))  
                {
                    $line->Append(" <-- [UPPERCASED]");  
                }
                echo $line . "\n";  
            }  
        }  

        static function printCommonArrayExceptions($arr)  
        {  
            // there is a bug throwing System\Exception(s) in Phalanger.
            // but apparently it has been quickly fixed after reported.
            try  
            {  
                /* Throwing System\Exception(s) do not get caught in
                 * the catch, instead they give an error message and 
                 * continue executing. i.e.
                 * throw new S\NullReferenceException("");                    
                 * throw new S\Exception("");
                */
                
                if (\is_null($arr))
                {
                    throw new \ErrorException(
                        "Object reference not set to an instance of an object.", 
                        0, \E_ERROR);                    
                }
                if (!isset($arr[100][100]))
                {
                    throw new \OutOfRangeException(
                        "Index was outside the bounds of the array.", 0);
                }      
            }  
            catch (\OutOfRangeException $ex)  
            {  
                echo "\nException: OutOfRangeException\n" . 
                    $ex->getMessage() . "\n";  
            } 
            catch (\ErrorException $ex)  
            {  
                echo "\nException: ErrorException " .
                    $ex->getSeverity() . "\n" . $ex->getMessage() . "\n";                
            }             
            /*catch (S\Exception $ex)
            {
                echo "\nException: ", "Exception", 
                    $ex->getMessage(), "\n";  
            }*/
        }  
        
        static function printTitle(string $message)
        {
            echo "\n";
            echo \str_repeat("=", 54) . "\n";
            echo $message . "\n";
            echo \str_repeat("=", 54) . "\n";
        }
    }

    [\Export]    
    class Alphabet implements \ArrayAccess   
    {    
        // Array Field
        private $letters = array();
        
        // Indexer Get/Set methods
        // Implementing ArrayAccess methods
        public function offsetSet($offset, $value) {
            if (\is_null($offset)) 
            {
                $this->letters[] = $value;
            } else 
            {
                $this->letters[$offset] = \strtoupper($value);
            }
        }
        public function offsetExists($offset) {
            return isset($this->letters[$offset]);
        }
        public function offsetUnset($offset) {
            unset($this->letters[$offset]);
        }
        public function offsetGet($offset) {
            return isset($this->letters[$offset]) ? $this->letters[$offset] : NULL;
        }
        
        // Read-Only Property  
        public function getLength()
        {  
            return \count($this->letters); 
        }  
        
        // Constructor 
        // No Overloaded Constructors support in (PHP) Phalanger 
        public function __construct($param = NULL)    
        {   
            // int $size
            if(\is_numeric($param))
            {
                $this->letters = \array_pad($this->letters, $size, ' '); 
            }
            // string $list
            else if(\is_string($param))
            {
                $this->letters = \str_split(\strtoupper($param));
            }
            // array $list
            else if(\is_array($param))
            {
                $this->letters = $param;
            }
            else 
            {
                $this->letters = NULL;
            }
        }    
        
        // Overridden Method
        public function __toString()    
        {    
            return \join(",", $this->letters); 
        }
        
        // Method  
        public function slice($start, $length)  
        {  
            return \array_slice($this->letters, $start, $length);              
        }  
    }    
}
?>


The output:






















































































Voilà, that's it. Next post in the following days.

Sunday, April 3, 2011

Factorial and Fibonacci in Phalanger



Update 1: using BigInteger Multiply method instead of unsupported custom * Operator.
Update 2: Porting code examples to Phalanger 3 - syntax changes on namespace use.

Here below a little program in Phalanger that implements 2 classes (in fact, they are 3). There is the main class, called Fiborial (Fibo(nnacci)+(Facto)rial) that implements the Fibonacci and the Factorial algorithms in two ways, one Recursive (using recursion) and the other Imperative (using loops and states). The second class is just an instance class that does the same thing, but its there just to show the difference between static and instance classes, and finally the third one (which will not appear in other languages) is the Program class which has the static execution method "Main".

You can also find 3 more little examples at the bottom. One prints out the Factorial's Series and Fibonacci's Series, the second one just shows a class that mixes both: static and instance members, and finally the third one that uses different return types (including System.Numerics.BigInteger) for the Factorial method to compare the timing and result.

As with the previous posts, you can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you some more basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2011/01/new-series-factorial-and-fibonacci.html 


The Fiborial Program

<?php      
# Factorial and Fibonacci in Phalanger        
namespace FiborialPhp;

use System;
use System\Collections\Generic as G;
use System\Diagnostics as D;
use System\Numerics as N;

# Instance Class           
# static is not a class modifier in PHP    
[\Export]
class StaticFiborial    
{      
    # Static Field     
    private static $className;    
    # no available static __constructor support    
    # Static Initializer Method instead, but need to be explicitly invoked    
    public static function StaticFiborialConstructor()    
    {                
        $className = "Static Constructor";    
        echo $className . "\n";    
    }            
    # Static Method - Factorial Recursive    
    public static function FactorialR(int $n)    
    {      
        if($n == 1)     
            return N\BigInteger::$One;  
        else                    
            return N\BigInteger::Multiply(new N\BigInteger($n), self::FactorialR($n-1));  
    }            
    # Static Method - Factorial Imperative        
    public static function FactorialI(int $n)     
    {                    
        $res = N\BigInteger::$One;
        for ($i = $n; $i >= 1; $i--)  
            $res = N\BigInteger::Multiply($res, new N\BigInteger($i));                  
        return $res;    
    }       
    # Static Method - Fibonacci Recursive        
    public static function FibonacciR(int $n)     
    {        
        if ($n < 2)    
            return 1;        
        else        
            return self::FibonacciR($n - 1) + self::FibonacciR($n - 2);        
    }    
    # Static Method - Fibonacci Imperative        
    public static function FibonacciI(int $n)     
    {    
        $pre = 0; $cur = 0; $tmp = 0;    
        $pre = 1; $cur = 1;    
        for ($i = 2; $i <= $n; $i++)     
        {    
            $tmp = $cur + $pre;        
            $pre = $cur;        
            $cur = $tmp;        
        }        
        return $cur;    
    }    
    # Static Method - Benchmarking Algorithms        
    public static function BenchmarkAlgorithm(int $algorithm, G\List<:int:> $values)     
    {    
        $timer = new D\Stopwatch();    
        $i = 0;     
        $testValue = 0;                
        $facTimeResult = N\BigInteger::$Zero;  
        $fibTimeResult = 0;        
                
        # "Switch" Flow Constrol Statement        
        switch ($algorithm)        
        {        
            case 1:        
                echo "\nFactorial Imperative:\n";    
                # "For" Loop Statement        
                for ($i = 0; $i < $values->Count; $i++)      
                {                                                    
                    $testValue = $values->get_Item($i);    
                    # Taking Time        
                    $timer->Start();        
                    $facTimeResult = self::FactorialI($testValue);        
                    $timer->Stop();                                
                    # Getting Time                              
                    echo " ($testValue) = {$timer->Elapsed->ToString()}\n";    
                }                            
                break;        
            case 2:        
                echo "\nFactorial Recursive:\n";    
                # "While" Loop Statement        
                while ($i < $values->Count)        
                {                                
                    $testValue = $values->get_Item($i);                            
                    # Taking Time        
                    $timer->Start();        
                    $facTimeResult = self::FactorialR($testValue);        
                    $timer->Stop();        
                    # Getting Time        
                    echo " ($testValue) = {$timer->Elapsed->ToString()}\n";    
                    $i++;    
                }    
                break;        
            case 3:        
                echo "\nFibonacci Imperative:\n";    
                # "Do-While" Loop Statement        
                do     
                {        
                    $testValue = $values->get_Item($i);    
                    # Taking Time        
                    $timer->Start();        
                    $fibTimeResult = self::FibonacciI($testValue);        
                    $timer->Stop();        
                    # Getting Time        
                    echo " ($testValue) = {$timer->Elapsed->ToString()}\n";    
                    $i++;        
                } while ($i < $values->Count);                            
                break;        
            case 4:        
                echo "\nFibonacci Recursive:\n";    
                # "ForEach" Loop Statement        
                foreach ($values as $item)        
                {        
                    $testValue = (int)$item;        
                    # Taking Time        
                    $timer->Start();        
                    $fibTimeResult = self::FibonacciR($testValue);    
                    $timer->Stop();        
                    # Getting Time        
                    echo " ($testValue) = {$timer->Elapsed->ToString()}\n";    
                }        
                break;        
            default:        
                echo "DONG!\n";    
                break;    
        }                        
    }        
}    
    
[\Export]     
# Instance Class    
class InstanceFiborial    
{      
    # Instance  Field     
    private $className;    
    # Instance Constructor                            
    function __construct()      
    {      
        $this->className = "Instance Constructor";    
        echo $this->className . "\n";    
    }    
    # Instance Method - Factorial Recursive    
    public function FactorialR(int $n)    
    {      
        # Calling Static Method    
        return StaticFiborial::FactorialR($n);    
    }    
    # Instance Method - Factorial Imperative        
    public function FactorialI(int $n)     
    {        
        # Calling Static Method    
        return StaticFiborial::FactorialI($n);    
    }       
    # Instance Method - Fibonacci Recursive        
    public function FibonacciR(int $n)     
    {        
        # Calling Static Method    
        return StaticFiborial::FibonacciR($n);    
    }    
    # Instance Method - Fibonacci Imperative        
    public function FibonacciI(int $n)     
    {    
        # Calling Static Method    
        return StaticFiborial::FibonacciI($n);    
    }    
}    
    
# Console Program      
class Program      
{      
    public static function Main()      
    {      
        # Static Initializer/Constructor for StaticFiborial Class     
        # explicitly called somewhere in your code ^_^    
        StaticFiborial::StaticFiborialConstructor();    
                
        echo "\nStatic Class\n";    
        # Calling Static Class and Methods      
        # No instantiation needed. Calling method directly from the class      
        echo "FacImp(5) = " . StaticFiborial::FactorialI(5)->ToString() . "\n";    
        echo "FacRec(5) = " . StaticFiborial::FactorialR(5)->ToString() . "\n";    
        echo "FibImp(11)= " . StaticFiborial::FibonacciI(11)->ToString() . "\n";    
        echo "FibRec(11)= " . StaticFiborial::FibonacciR(11)->ToString() . "\n";    
      
        echo "\nInstance Class\n";      
        # Calling Instance Class and Methods      
        # Need to instantiate before using. Calling method from instantiated object      
        $ff = new InstanceFiborial();    
        echo "FacImp(5) = {$ff->FactorialI(5)->ToString()}\n";    
        echo "FacRec(5) = {$ff->FactorialR(5)->ToString()}\n";    
        echo "FibImp(11)= {$ff->FibonacciI(11)->ToString()}\n";    
        echo "FibRec(11)= {$ff->FibonacciR(11)->ToString()}\n";    
                              
        # From 5 to 50 by 5    
        $values = new G\List<:int:>;    
        for($i = 5; $i <= 50; $i += 5)    
            $values->Add($i);    
    
        # Benchmarking Fibonacci      
        # 1 = Factorial Imperative      
        StaticFiborial::BenchmarkAlgorithm(1, $values);    
        # 2 = Factorial Recursive      
        StaticFiborial::BenchmarkAlgorithm(2, $values);    
        # Benchmarking Factorial      
        # 3 = Fibonacci Imperative      
        StaticFiborial::BenchmarkAlgorithm(3, $values);    
        # 4 = Fibonacci Recursive      
        StaticFiborial::BenchmarkAlgorithm(4, $values);    
    
        # Stop and exit      
        echo "Press any key to exit...";      
        fgets(STDIN);
        return 0;      
    }      
}    
 
?>

And the Output is:




































Printing the Factorial and Fibonacci Series
<?php        
namespace FiborialSeries;
use System;
use System\Text as T;    
use System\Numerics as N;
      
[\Export]
class Fiborial    
{      
    # Using a StringBuilder as a list of string elements                
    static function GetFactorialSeries(int $n)     
    {            
        # Create the String that will hold the list        
        $series = new T\StringBuilder();        
        # We begin by concatenating the number you want to calculate        
        # in the following format: "!# ="        
        $series->Append("!");        
        $series->Append($n);        
        $series->Append(" = ");        
        # We iterate backwards through the elements of the series        
        for ($i = $n; $i <= $n && $i > 0; $i--)     
        {        
            # and append it to the list        
            $series->Append($i);    
            if ($i > 1)        
                $series->Append(" * ");        
            else         
                $series->Append(" = ");         
        }        
        # Get the result from the Factorial Method        
        # and append it to the end of the list                                        
        # $series->Append(self::Factorial($n)->ToString());    
        # BUT! that throws an exception with big numbers (> fact(30))    
        # Overflow ex "Value was either too large or too small for a Decimal."  
        # because I think it is a bug i used an ugly workaround which is  
        # using the "." in the return.  
        return $series->ToString() . self::Factorial($n)->ToString();  
    }        
        
    # Using a StringBuilder as a list of string elements        
    static function GetFibonnaciSeries(int $n)        
    {        
        # Create the String that will hold the list        
        $series = new T\StringBuilder();    
        # We begin by concatenating the first 3 values which        
        # are always constant        
        $series->Append("0, 1, 1");        
        # Then we calculate the Fibonacci of each element        
        # and add append it to the list        
        for ($i = 2; $i <= $n; $i++)        
        {        
            if ($i < $n)        
                $series->Append(", ");        
            else        
                $series->Append(" = ");        
            
            $series->Append(self::Fibonacci($i));    
        }        
        # return the list as a string        
        return $series->ToString();        
    }        
    
    static function Factorial(int $n)    
    {      
        if($n == 1)     
            return new N\BigInteger(1);  
        else                    
            return N\BigInteger::Multiply(new N\BigInteger($n), self::Factorial($n - 1));  
    }    
            
    static function Fibonacci(int $n)     
    {        
        if ($n < 2)    
            return 1;    
        else        
            return self::Fibonacci($n - 1) + self::Fibonacci($n - 2);        
    }        
}    
    
class Program      
{      
    public static function Main()      
    {      
        # Printing Factorial Series        
        echo "\n";    
        echo Fiborial::GetFactorialSeries(5) . "\n";    
        echo Fiborial::GetFactorialSeries(7) . "\n";    
        echo Fiborial::GetFactorialSeries(9) . "\n";    
        echo Fiborial::GetFactorialSeries(11) . "\n";    
        echo Fiborial::GetFactorialSeries(40) . "\n";      
        # Printing Fibonacci Series  
        echo "\n";    
        echo Fiborial::GetFibonnaciSeries(5) . "\n";    
        echo Fiborial::GetFibonnaciSeries(7) . "\n";    
        echo Fiborial::GetFibonnaciSeries(9) . "\n";    
        echo Fiborial::GetFibonnaciSeries(11) . "\n";    
        echo Fiborial::GetFibonnaciSeries(40) . "\n";    
                 
        fgets(STDIN);
        return 0;      
    }      
}    
?>

And the Output is:

















Mixing Instance and Static Members in the same Class

Instance classes can contain both, instance and static members such as: fields, properties, constructors, methods, etc.

<?php    
namespace FiborialExtras2;
use System;

# Instance Class  
[\Export]       
class Fiborial  
{    
    # Instance Field  
    private $instanceCount;  
    # Static Field  
    private static $staticCount;          
    # Instance Read-Only Property/Getter  
    # Within instance members, you can always use    
    # the "this" reference pointer to access your (instance) members.  
    public function getInstanceCount()  
    {  
        return $this->instanceCount;  
    }  
    # Static Read-Only Property/Getter  
    # As with Static Methods, you cannot reference your class members  
    # with the "this" reference pointer since static members are not  
    # instantiated.          
    public static function getStaticCount()  
    {  
        return $staticCount;  
    }  
    # Instance Constructor            
    public function __construct()    
    {    
        $this->instanceCount = 0;  
        echo "\nInstance Constructor {$this->instanceCount}\n";  
    }    
    # Static Constructor  
    public static function FiborialStaticConstructor()  
    {  
        $staticCount = 0;  
        echo "\nStatic Constructor {$staticCount}\n";  
    }      
    # Instance Method  
    public function Factorial(int $n)  
    {    
        $this->instanceCount += 1;  
        echo "\nFactorial({$n})\n";  
    }  
    # Static Method  
    public static function Fibonacci(int $n)   
    {      
        $staticCount += 1;  
        echo "\nFibonacci({$n})\n";  
    }      
}  
  
class Program    
{    
    public static function Main()    
    {    
        # Calling Static Constructor/Initializer and Methods  
        # No need to instantiate  
        Fiborial::FiborialStaticConstructor();  
        Fiborial::Fibonacci(5);              
  
        // Calling Instance Constructor and Methods  
        // Instance required  
        $fib = new Fiborial();  
        $fib->Factorial(5);  
  
        Fiborial::Fibonacci(15);              
        $fib->Factorial(5);  
  
        // Calling Instance Constructor and Methods  
        // for a second object  
        $fib2 = new Fiborial();  
        $fib2->Factorial(5);  
              
        echo "\n";  
        // Calling Static Property  
        echo "Static Count = " . Fiborial::getStaticCount() . "\n";  
        // Calling Instance Property of object 1 and 2  
        echo "Instance 1 Count = {$fib->getInstanceCount()}\n";  
        echo "Instance 2 Count = {$fib2->getInstanceCount()}\n";  
  
        fgets(STDIN);    
        return 0;    
    }    
}  
?>

And the Output is:























Factorial using System.Int64, System.Double, System.Numerics.BigInteger

The Factorial of numbers over 20 are massive!
For instance: !40 = 815915283247897734345611269596115894272000000000!
Because of this, the previous version of this program was giving the "wrong" result
!40 = -70609262346240000 when using "long" (System.Int64) type, but it was not until I did the Fiborial version in VB.NET that I realized about this faulty code, because instead of giving me a wrong value, VB.NET, JScript.NET, Boo execution thrown an Overflow Exception when using the "Long/long" (System.Int64) type.

My first idea was to use ulong and ULong, but both failed for "big" numbers. I then used Double (double floating point) type and got no more exception/wrong result. The result of the factorial was now correct !40 = 1.1962222086548E+56, but still I wanted to show the Integer value of it, so I did some research and found that there is a new System.Numerics.BigInteger class in the .NET Framework 4.0. Adding the reference to the project and using this new class as the return type of the Factorial methods, I was able to get the result I was expecting.
!40 = 815915283247897734345611269596115894272000000000

What I also found was that using different types change the time the algorithm takes to finish:
System.Int64 < System.Double < System.Numerics.BigInteger
Almost by double!

To illustrate what I just "tried" to say, lets have a look at the following code and the output we get.

<?php      
use System\Numerics as N;
use System\Diagnostics as D;      
    
function FactorialInt64(int $n)     
{        
    if ($n == 1)        
        return 1;        
    else        
        return $n * FactorialInt64($n - 1);        
}        
    
function FactorialDouble(int $n)     
{        
    if ($n == 1)        
        return (double)1;        
    else        
        return (double)($n * FactorialDouble($n - 1));    
}    
    
function FactorialBigInteger(int $n)     
{        
    if($n == 1)     
        return N\BigInteger::$One;  
    else                    
        return N\BigInteger::Multiply(new N\BigInteger($n), FactorialBigInteger($n - 1));  
}    
    
class Program    
{    
    public static function Main()      
    {      
            $timer = new D\Stopwatch();    
            $facIntResult = 0;        
            $facDblResult = (double)0;        
            $facBigResult = N\BigInteger::$Zero;     
    
            echo "\nFactorial using Int64\n";        
            // Benchmark Factorial using Int64        
            for ($i = 5; $i <= 50; $i += 5)        
            {        
                $timer->Start();        
                $facIntResult = FactorialInt64($i);        
                $timer->Stop();        
                echo " ({$i}) = {$timer->Elapsed->ToString()} : {$facIntResult}\n";    
            }                    
            echo "\nFactorial using Double\n";        
            // Benchmark Factorial using Double    
            for ($i = 5; $i <= 50; $i += 5)        
            {        
                $timer->Start();        
                $facDblResult = FactorialDouble($i);        
                $timer->Stop();        
                echo " ({$i}) = {$timer->Elapsed->ToString()} : {$facDblResult}\n";    
            }        
            echo "\nFactorial using N\BigInteger\n";    
            // Benchmark Factorial using N\BigInteger                    
            for ($i = 5; $i <= 50; $i += 5)    
            {        
                    
                $timer->Start();        
                $facBigResult = FactorialBigInteger($i);        
                $timer->Stop();        
                echo " ({$i}) = {$timer->Elapsed->ToString()} : {$facBigResult->ToString()}\n";    
            }      
                          
            fgets(STDIN);      
            return 0;      
    }      
}    
?>

NOTE: you need to manually add a reference to the System.Numerics.dll assembly to your project so you can add it to your code.

And the Output is:

 

Saturday, October 23, 2010

Phalanger - Basics by Example



Update 1: Porting code examples to Phalanger 3 - syntax changes on namespace use.

Continue with the Basics by Example; today's version of the post written in Phalanger (PHP) Enjoy!

You can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you the basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2010/08/new-series-languages-basics-by-example.html 



Greetings Program - Verbose
<?php  
// Phalanger Basics  
namespace PhpGreetProgram;
use System\DateTime;  

[\Export]  
class Greet  
{  
    // Fields or Attributes  
    private $message;  
    private $name;  
    private $loopMessage;  
    // Getters and Setters. No Properties built-in syntax availabe (yet)  
    public function GetMessage()  
    {  
        return $this->message;  
    }  
    public function SetMessage($value)  
    {  
        $this->message = $this->Capitalize($value);  
    }  
    public function GetName()  
    {  
        return $this->name;  
    }  
    public function SetName($value)  
    {  
        $this->name = $this->Capitalize($value);  
    }  
    public function GetLoopMessage()  
    {  
        return $this->loopMessage;  
    }  
    public function SetLoopMessage($value)  
    {  
        $this->loopMessage = $value;  
    }  
    // Constructor          
    public function __construct()  
    {  
        $this->message = "";  
        $this->name = "";  
        $this->loopMessage = 0;  
    }  
    // Overloaded Constructors   
    // No Overloaded Constructors support in Phalanger          
    // Method 1  
    private function Capitalize($value)  
    {              
        // "if-then-else" statement  
        if (strlen($value) >= 1)  
        {  
            return ucwords($value);  
        }  
        else   
        {  
            return "";  
        }  
    }  
    // Method 2  
    public function Salute()  
    {  
        // "for" statement  
        for ($i = 0; $i < $this->loopMessage; $i++)  
        {  
            echo "{$this->message} {$this->name}!\n";  
        }  
    }  
    // Overloaded Method  
    // No Overloaded Methods Support in Phalanger. News methods instead.  
    // Method 2.1  
    public function Salute21($message, $name, $loopMessage)  
    {  
        // "while" statement  
        $i = 0;  
        while ($i < $loopMessage)  
        {  
            echo "{$this->Capitalize($message)} {$this->Capitalize($name)}!\n";  
            $i++;  
        }  
    }  
    // Method 2.2  
    public function Salute22($name)  
    {  
        // "switch/case" statement  
        $dtNow = DateTime::$Now;              
        switch(intval($dtNow->Hour))  
        {  
            case 6: case 7: case 8: case 9: case 10: case 11:  
                $this->message = "good morning,";  
                break;  
            case 12: case 13: case 14: case 15: case 16: case 17:  
                $this->message = "good afternoon,";  
                break;  
            case 18: case 19: case 20: case 21: case 22:  
                $this->message = "good evening,";  
                break;  
            case 23: case 0: case 1: case 2: case 3: case 4: case 5:  
                $this->message = "good night,";  
                break;  
            default:  
                $this->message = "huh?";  
                break;  
        }  
        echo "{$this->Capitalize($this->message)} {$this->Capitalize($name)}!\n";  
    }  
}  
  
// Console Program  
class Program  
{  
    public static function Main()  
    {  
        // Define variable of type Greet and instantiate. Call Constructor  
        $g = new Greet();  
        // Call Setters  
        $g->SetMessage("hello");  
        $g->SetName("world");  
        $g->SetLoopMessage(5);  
        // Call Method 2  
        $g->Salute();  
        // Call Method 2.1 and Getters  
        $g->Salute21($g->GetMessage(), "phalanger", $g->GetLoopMessage());  
        // Call Method 2.2  
        $g->Salute22("carlos");  
        // Stop and exit  
        echo "Press any key to exit...";  
        fgets(STDIN);  
        return 0;  
    }  
}  
?>

Greetings Program - Minimal
<?php
// Phalanger Basics  
use System\DateTime;  

class Greet  
{  
    // Fields or Attributes  
    private $message;  
    private $name;  
    private $loopMessage;  
    // Getters and Setters. No Properties built-in syntax availabe (yet)  
    function GetMessage()  
    {  
        return $this->message;  
    }  
    function SetMessage($value)  
    {  
        $this->message = $this->Capitalize($value);  
    }  
    function GetName()  
    {  
        return $this->name;  
    }  
    function SetName($value)  
    {  
        $this->name = $this->Capitalize($value);  
    }  
    function GetLoopMessage()  
    {  
        return $this->loopMessage;  
    }  
    function SetLoopMessage($value)  
    {  
        $this->loopMessage = $value;  
    }  
    // Constructor          
    function __construct()  
    {  
        $this->message = "";  
        $this->name = "";  
        $this->loopMessage = 0;  
    }  
    // Overloaded Constructors   
    // No Overloaded Constructors support in Phalanger          
    // Method 1  
    private function Capitalize($value)  
    {              
        // "if-then-else" statement  
        if (strlen($value) >= 1)  
        {  
            return ucwords($value);  
        }  
        else   
        {  
            return "";  
        }  
    }  
    // Method 2  
    function Salute()  
    {  
        // "for" statement  
        for ($i = 0; $i < $this->loopMessage; $i++)  
        {  
            echo "{$this->message} {$this->name}!\n";  
        }  
    }  
    // Overloaded Method  
    // No Overloaded Methods Support in Phalanger. News methods instead.  
    // Method 2.1  
    function Salute21($message, $name, $loopMessage)  
    {  
        // "while" statement  
        $i = 0;  
        while ($i < $loopMessage)  
        {  
            echo "{$this->Capitalize($message)} {$this->Capitalize($name)}!\n";  
            $i++;  
        }  
    }  
    // Method 2.2  
    function Salute22($name)  
    {  
        // "switch/case" statement  
        $dtNow = DateTime::$Now;              
        switch(intval($dtNow->Hour))  
        {  
            case 6: case 7: case 8: case 9: case 10: case 11:  
                $this->message = "good morning,";  
                break;  
            case 12: case 13: case 14: case 15: case 16: case 17:  
                $this->message = "good afternoon,";  
                break;  
            case 18: case 19: case 20: case 21: case 22:  
                $this->message = "good evening,";  
                break;  
            case 23: case 0: case 1: case 2: case 3: case 4: case 5:  
                $this->message = "good night,";  
                break;  
            default:  
                $this->message = "huh?";  
        }  
        echo "{$this->Capitalize($this->message)} {$this->Capitalize($name)}!\n";  
    }  
}  
  
// Console Program  
class Program  
{  
    static function Main()  
    {  
        // Define variable of type Greet and instantiate. Call Constructor  
        $g = new Greet();  
        // Call Setters  
        $g->SetMessage("hello");  
        $g->SetName("world");  
        $g->SetLoopMessage(5);  
        // Call Method 2  
        $g->Salute();  
        // Call Method 2.1 and Getters  
        $g->Salute21($g->GetMessage(), "phalanger", $g->GetLoopMessage());  
        // Call Method 2.2  
        $g->Salute22("carlos");  
        // Stop and exit  
        echo "Press any key to exit...";  
        fgets(STDIN);  
    }  
}  
?>

And the Output is:



Emulating Overloaded Constructor in Phalanger (PHP)
PHP and Phalanger do not support Overloading Constructors (at least not so far, in the version I'm using), but there is another way you can "emulate" that by creating one constructor with all parameters you need, but assigning a default value to them and then, validating that if you provide those parameters, you use them, otherwise, default init values will be use as shown here below.

<?
class Greet
{    # Fields or Attributes
    private $message;
    private $name;
    private $loopMessage;    
    # Constructor
    function __construct($message=false, $name=false, $loopMessage=false)
    {
        # Use Constructor parameter only if it is was supplied if not use default
        if($message)
            $this->message = $message;
        else
            $this->message = "bye";
        if($name)
            $this->name = $name;
        else
            $this->name = "carlos";
        if($loopMessage)
            $this->loopMessage = $loopMessage;
        else
            $this->loopMessage = 0;
    }        
    // Method 2
    function Salute()
    {
        echo "{$this->loopMessage} {$this->message} {$this->name}!\n";
    }
}

// Console Program
class Program
{
    static function Main()
    {
        // Call Constructor using Defaults
        $g = new Greet();
        $g->Salute();
        // Call Constructor using Parameters
        $g = new Greet("hello", "world", 5);
        $g->Salute();
        // Stop and exit
        echo "Press any key to exit...";
        fgets(STDIN);
    }
}
?>

And the Output is:

Saturday, June 19, 2010

OO Hello World - Phalanger



Phalanger version of the OO Hello World is here!
Phalanger is a PHP compiler targeting the .NET CLR. It allows you to create any type of .net applications, not only Web apps, but also console, windows forms, and libraries using the PHP language and libraries.

If you are new to the PHP programming language you can go to the Phalanger Info section.


By the way, you can see my previous post here: http://carlosqt.blogspot.com/2010/06/oo-hello-world.html
where I give some details on WHY these "OO Hello World series" samples. 

Version 1 (Minimal):
The minimum you need to type to get your program compiled and running.
<?
class Greet 
{
    private $name;
    function __construct($name)
    {    
        $this->name = ucwords($name);
    }
    function Salute()
    {
        echo "Hello {$this->name}!";        
    }
}

// Greet the world!
class Program
{
    static function Main()
    {                    
        $g = new Greet("world");
        $g->Salute();
    }
}
?>

Version 2 (Verbose):
Explicitly adding instructions and keywords that are optional to the compiler.
<?php
import namespace System;
namespace GreetProgram
{   
    [Export] 
    class Greet 
    {
        private $name;
        public function __construct($name)
        {
            $this->name = ucwords($name);
        }
        public function Salute()
        {
            echo "Hello {$this->name}!";
        }
    }

    // Greet the world!
    class Program
    {
        public static function Main()
        {                    
         $g = new GreetProgram:::Greet("world");
         $g->Salute();         
        }
    }
}
?>

The Program Output:










Phalanger Info:

“Phalanger is a project which was started at Charles University in Prague and was supported by Microsoft. It compiles source code written in the PHP scripting language into CIL byte-code. It handles the beginning of a compiling process which is completed by the JIT compiler component of the .NET Framework. It does not address native code generation nor optimization. Its purpose is to compile PHP scripts into .NET assemblies, logical units containing CIL code and meta-data. Phalanger can run real-world PHP applications, many with minor to no modifications.” Taken from: (http://en.wikipedia.org/wiki/Phalanger_(compiler))

Appeared:
2003
Current Version:
Developed by:
Tomas Matousek, Ladislav Prosek, Vaclav Novak, Pavel Novak, Jan Benda, and Martin Maly
Creator:
Tomas Matousek, Ladislav Prosek
Influenced by:
PHP (Rasmus Lerdorf)
Predecessor Language
Predecessor Appeared
Predecessor Creator
Runtime Target:
CLR
Latest Framework Target:
2.0
Mono Target:
Yes
Allows Unmanaged Code:
No
Source Code Extension:
“.php”
Keywords:
92
Case Sensitive:
No
Free Version Available:
Yes
Open Source:
Yes
Standard:
No
Latest IDE Support:
Visual Studio 2008 (pro, shell)
Language Reference:
Extra Info: