Showing posts with label DelphiPrism. Show all posts
Showing posts with label DelphiPrism. Show all posts

Friday, July 5, 2013

Arrays and Indexers in Oxygene



Today's post is about Arrays and Indexers in Oxygene. 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 Oxygene, in this case, compared to all other 22 languages on future posts, which essentially, is the real aim behind this blog.

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 VB.NET 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. You can get a Oxygene Trial version with IDE support, or get the Free Command Line version and run it from the console.

Last thing. 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.

namespace OxygeneArrays;

interface

type
  Program = class
  public
    class method Main(args: array of String);
    class method ReverseChar(arr: array of Char): array of Char;  
    class method BubbleSortInt(arr: array of Integer): array of Integer;
    class method BubbleSortString(arr: array of String): array of String;
    class method TransposeMatrix(m: array[0..,0..] of Integer): array[0..,0..] of Integer;
    class method UpperCaseRandomArray(arr: array of array of String);
    class method PrintArrayChar(arr: array of Char);
    class method PrintArrayInt(arr: array of Integer);
    class method PrintArrayString(arr: array of String);  
    class method PrintMatrix(m: array[0..,0..] of Integer);
    class method GraphJaggedArray(arr: array of array of String);  
    class method PrintJaggedArray(arr: array of array of String);  
    class method PrintCommonArrayExceptions(arr: array of array of String);
    class method PrintTitle(message: String);   
  end;
  
type     
  Alphabet = public class  
  private  
    // Array Field  
    var letters: array of Char;  
  public      
    // Read-Only Property
    property Length: Integer read letters.Length;    
    // Indexer Get/Set Property
    property Item[idx: Integer]: Char read GetItem write SetItem; default;
    method GetItem(idx: Integer): Char;
    method SetItem(idx: Integer; value: Char);
    // Constructors
    constructor(size: Integer);
    constructor(list: String);
    constructor(list: array of Char);
    // Overriden Method
    method ToString: String; override;   
    // Method  
    method Slice(start: Integer; len: Integer): array of Char;
  end;  
*)
implementation

class method Program.Main(args: array of String);
var
  // Declare Array of Chars  
  letters, inverse_letters: array of Char;  
  // Declare Array of Integers 
  numbers, ordered_numbers: array of Integer;
  // Declare Array of String 
  names, ordered_names: array of String;
  // Declare Matrix
  transposed_matrix: array[0.., 0..] of Integer;
  // other vars
  word1,word2,word3: String;
begin  
  // Single-dimensional Array(s)  
  
  PrintTitle('Reverse Array Elements');

  // Initialize Array of Chars 
  letters := new Char[5];  
  letters[0] := 'A';  
  letters[1] := 'E';  
  letters[2] := 'I';  
  letters[3] := 'O';  
  letters[4] := 'U';  

  PrintArrayChar(letters); 
  inverse_letters := ReverseChar(letters);  
  PrintArrayChar(inverse_letters);  

  PrintTitle('Sort Integer Array Elements');  
  
  // Declare and Initialize Array of Integers   
  numbers := [ 10, 8, 3, 1, 5 ];  
  PrintArrayInt(numbers);  
  ordered_numbers := BubbleSortInt(numbers);  
  PrintArrayInt(ordered_numbers);  
  
  PrintTitle('Sort String Array Elements');  
  
  // Initialize and Array of Strings  
  names := [             
      'Damian',   
      'Rogelio',  
      'Carlos',   
      'Luis',             
      'Daniel'  
      ];  
  PrintArrayString(names);  
  ordered_names := BubbleSortString(names);  
  PrintArrayString(ordered_names);  
  
  // Multi-dimensional Array (Matrix row,column)  
  
  PrintTitle('Transpose Matrix');  
  
  (* Matrix row=2,col=3 
   * A =  [6  4 24] 
   *      [1 -9  8] 
  *)  
  // Array inline expression used to declare and initialize array
  var matrix: array[0..1, 0..2] of Integer := [ [ 6, 4, 24 ], 
                          [ 1, -9, 8 ] ]; 

  PrintMatrix(matrix);  
  transposed_matrix := TransposeMatrix(matrix);  
  PrintMatrix(transposed_matrix);  
  
  // Jagged Array (Array-of-Arrays)  
  
  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: 
  *  
  * var text: array of array of String := [    
  *    [ 'word1', 'word2', 'wordN' ], 
  *    [ 'word1', 'word2', 'wordM' ],   
  *    ... 
  *    ]; 
  *  
  * Text extract from: 'El ingenioso hidalgo don Quijote de la Mancha' 
  *  
  *)  
  var text: array of array of String := [   
  'Hoy es el día más hermoso de nuestra vida, querido Sancho;'.Split(' '),  
  'los obstáculos más grandes, nuestras propias indecisiones;'.Split(' '),  
  'nuestro enemigo más fuerte, miedo al poderoso y nosotros mismos;'.Split(' '),  
  'la cosa más fácil, equivocarnos;'.Split(' '),  
  'la más destructiva, la mentira y el egoísmo;'.Split(' '),  
  'la peor derrota, el desaliento;'.Split(' '),  
  'los defectos más peligrosos, la soberbia y el rencor;'.Split(' '),  
  'las sensaciones más gratas, la buena conciencia...'.Split(' ')   
  ];  

  PrintJaggedArray(text);  
  UpperCaseRandomArray(text);  
  PrintJaggedArray(text);  
  GraphJaggedArray(text);  
  
  // Array Exceptions  
  
  PrintTitle('Common Array Exceptions');  
  
  PrintCommonArrayExceptions(Nil);  
  PrintCommonArrayExceptions(text);  
  
  // Accessing Class Array Elements through Indexer  
  
  PrintTitle('Alphabets');  

  var vowels: Alphabet := new Alphabet(5);  
  vowels[0] := 'a';  
  vowels[1] := 'e';  
  vowels[2] := 'i';  
  vowels[3] := 'o';  
  vowels[4] := 'u';

  Console.WriteLine(''#10'Vowels = {{{0}}}',  
    String.Join(',', vowels[0], vowels[1], vowels[2], vowels[3], vowels[4]));  
  
  var en: Alphabet := new Alphabet('abcdefghijklmnopqrstuvwxyz');  
  Console.WriteLine('English Alphabet = {{{0}}}', en.ToString);  
  
  Console.WriteLine('Alphabet Extract en[9..19] = {{{0}}}',   
          new Alphabet(en.Slice(9, 10)));  
  
  word1 := String.Join('', en[6], en[14], en[14], en[3]);  
  word2 := String.Join('', en[1], en[24], en[4]);  
  word3 := String.Join('', en[4], en[21], en[4], en[17],  
                           en[24], en[14], en[13], en[4]);  
  
  Console.WriteLine(''#10'{0} {1}, {2}!'#10'', word1, word2, word3);  

  Console.Read;
end;

class method Program.ReverseChar(arr: array of Char): array of Char; 
var 
  reversed: array of Char;
  i: Integer;
begin
  i := 0;
  reversed := new Char[arr.Length];
  for j: Integer := arr.Length - 1 downto 0 do
  begin
    reversed[i] := arr[j];
    i := i + 1;
  end;
  result := reversed;
end;

class method Program.BubbleSortInt(arr: array of Integer): array of Integer; 
var
  swap: Integer;
begin
  swap := 0;
  for i: Integer := arr.Length - 1 downto 1 do
  begin
    for j: Integer := 0 to i - 1 do
    begin
      if arr[j] > arr[j + 1] then
      begin
        swap := arr[j];  
        arr[j] := arr[j + 1];  
        arr[j + 1] := swap; 
      end;
    end;
  end;
  result := arr;
end;

class method Program.BubbleSortString(arr: array of String): array of String; 
var
  swap: String;
begin
  swap := '';
  for i: Integer := arr.Length - 1 downto 1 do
  begin
    for j: Integer := 0 to i - 1 do
    begin
      if arr[j][0] > arr[j + 1][0] then
      begin
        swap := arr[j];  
        arr[j] := arr[j + 1];  
        arr[j + 1] := swap; 
      end;
    end;
  end;
  result := arr;
end;

class method Program.TransposeMatrix(m: array[0..,0..] of Integer): array[0..,0..] of Integer;
var 
  transposed: array[0..,0..] of Integer;  
begin
  (* Transposing a Matrix 2,3  
   *  
   * A =  [6  4 24]T [ 6  1]  
   *      [1 -9  8]  [ 4 -9] 
   *                 [24  8] 
   *)  
  transposed := new Integer[m.GetUpperBound(1) + 1,  
                m.GetUpperBound(0) + 1];
  for i: Integer := 0 to m.GetUpperBound(0) do  
  begin
    for j: Integer := 0 to m.GetUpperBound(1) do
    begin
      transposed[j, i] := m[i, j];  
    end;
  end;
  result := transposed;
end;

class method Program.UpperCaseRandomArray(arr: array of array of String);
var
  r: Random;
  i: Integer;
begin
  r := new Random;
  i := r.Next(0, arr.Length - 1);
  for j: Integer := 0 to arr[i].Length - 1 do
  begin
    arr[i][j] := arr[i][j].ToUpper;
  end;
end;

class method Program.PrintArrayChar(arr: array of Char); 
begin
  Console.WriteLine(''#10'Print Array Content {0}',  
    arr.GetType.Name.Replace(']', arr.Length.ToString + ']'));  
  
  for i: Integer := 0 to arr.Length - 1 do
  begin
    Console.WriteLine(' array [{0,2}] = {1,2} ', i, arr[i]);  
  end;
end;

class method Program.PrintArrayInt(arr: array of Integer); 
begin
  Console.WriteLine(''#10'Print Array Content {0}',  
    arr.GetType.Name.Replace(']', arr.Length.ToString + ']'));  
  
  for i: Integer := 0 to arr.Length - 1 do
  begin
    Console.WriteLine(' array [{0,2}] = {1,2} ', i, arr[i]);  
  end;
end;

class method Program.PrintArrayString(arr: array of String); 
begin
  Console.WriteLine(''#10'Print Array Content {0}',  
    arr.GetType.Name.Replace(']', arr.Length.ToString + ']'));  
  
  for i: Integer := 0 to arr.Length - 1 do
  begin
    Console.WriteLine(' array [{0,2}] = {1,2} ', i, arr[i]);  
  end;
end;

class method Program.PrintMatrix(m: array [0 .. ,0 .. ] of Integer); 
begin
  Console.WriteLine(''#10'Print Matrix Content {0}[{1},{2}]',  
    m.GetType.Name.Replace('[,]', ''),  
    (m.GetUpperBound(0) + 1).ToString,  
    (m.GetUpperBound(1) + 1).ToString);  

  for i: Integer := 0 to m.GetUpperBound(0) do
  begin
    for j: Integer := 0 to m.GetUpperBound(1) do
    begin
      Console.WriteLine(' array [{0,2},{1,2}] = {2,2} ', i, j, m[i, j]);
    end;
  end; 
end;

class method Program.GraphJaggedArray(arr: array of array of String);
var
  lineCount: Integer;
begin
  (* When using Arrays, we can use foreach instead of for:  
  *  
  * for i: Integer := 0 to arr.Length - 1 do
  *   for j: Integer := 0 to arr.Length - 1 do
  *  
  *)  
  Console.WriteLine(''#10'Print Text Content {0}', arr.GetType.Name); 
  lineCount := 1;    
  for each s: array of String in arr do
  begin
    Console.Write('Line{0,2}|', lineCount); 
    for each w: String in s do
    begin
      Console.Write('{0,3}', '*');
    end;
    Console.WriteLine(' ({0})', s.Length);
    lineCount := lineCount + 1;
  end;
end;

class method Program.PrintJaggedArray(arr: array of array of String); 
var
  line: System.Text.StringBuilder;
begin
  Console.WriteLine(''#10'Print Jagged Array Content {0}', arr.GetType.Name);
  for i: Integer := 0 to arr.Length - 1 do
  begin
    line := new System.Text.StringBuilder;  
    for j: Integer := 0 to arr[i].Length - 1 do
    begin
      line.Append(' ' + arr[i][j]);  
    end;
    if line.ToString() = line.ToString.ToUpper then
    begin
      line.Append(' <-- [UPPERCASED]');  
    end;    
    Console.WriteLine(line);  
  end;
end;

class method Program.PrintCommonArrayExceptions(arr: array of array of String); 
begin
  try
    arr[100][100] := 'hola';  
  except
    on ex: Exception do
      Console.WriteLine(''#10'Exception: '#10'{0}'#10'{1}', 
              ex.GetType().Name, ex.Message); 
  end;
end;

class method Program.PrintTitle(message: String); 
begin
  Console.WriteLine;  
  Console.WriteLine('======================================================');  
  Console.WriteLine('{0,10}', message);  
  Console.WriteLine('======================================================');  
end;

// Indexer Get/Set Property
method Alphabet.GetItem(idx: Integer): Char;
begin
  result := self.letters[idx];
end;

method Alphabet.SetItem(idx: Integer; value: Char); 
begin
  self.letters[idx] := Char.ToUpper(value);
end;

// Constructors
constructor Alphabet(size: Integer);
begin
  self.letters := new Char[size];
end;

constructor Alphabet(list: String);
begin
  self.letters := list.ToUpper.ToCharArray;
end;

constructor Alphabet(list: array of Char);
begin
  self.letters := list;
end;

// Overridden Method  
method Alphabet.ToString: String;
begin
  result := String.Join(',', self.letters); 
end;

// Method  
method Alphabet.Slice(start: Integer; len: Integer): array of Char;
var
  res: array of Char;
  i, j: Integer;
begin
  res := new Char[len];
  j := start;
  for i := 0 to len - 1 do
  begin
    res[i] := self[j];
    j := j + 1;
  end;
  result := res;
end;

end.


The output:






















































































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

Saturday, February 26, 2011

Factorial and Fibonacci in Oxygene



Here below a little program in Oxygene 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

// Factorial and Fibonacci in Delphi Prism
namespace FiborialDelphi;

interface
uses
    System,
    System.Diagnostics,
    System.Collections.Generic,
    System.Numerics;

type
    // Static Class 
    StaticFiborial = public static class
    private
        // Static/Class Field
        class var 
            fClassName: string;        
    public
        // Static/Class Constructor 
        class constructor;
        // Static/Class Method - Factorial Recursive    
        class method FactorialR(n: integer): BigInteger;
        // Static/Class Method - Factorial Imperative
        class method FactorialI(n: integer): BigInteger;
        // Static/Class Method - Fibonacci Recursive
        class method FibonacciR(n: integer): Int64;
        // Static/Class Method - Fibonacci Imperative
        class method FibonacciI(n: integer): Int64;
        // Static/Class Method - Benchmarking Algorithms 
        class method BenchmarkAlgorithm(algorithm: integer; values: List<integer>);
    end;

type
    // Instance Class 
    InstanceFiborial = public class
    private
        // Instance Field
        var
            fClassName: string;
    public
        // Instance Constructor 
        constructor;
        // Instance Method - Factorial Recursive    
        method FactorialR(n: integer): BigInteger;
        // Instance Method - Factorial Imperative
        method FactorialI(n: integer): BigInteger;
        // Instance Method - Fibonacci Recursive
        method FibonacciR(n: integer): Int64;
        // Instance Method - Fibonacci Imperative
        method FibonacciI(n: integer): Int64;
    end;

type
    ConsoleApp = class
    public
        class method Main(args: array of string);
    end;

implementation

// Static/Class Constructor   
class constructor StaticFiborial;
begin
    fClassName := 'Static/Class Constructor';
    Console.WriteLine(fClassName);
end;
// Static/Class Method - Factorial Recursive    
class method StaticFiborial.FactorialR(n: integer): BigInteger;
begin
    if n = 1 then 
        result := 1
    else 
        result := n * FactorialR(n - 1);
end;
// Static/Class Method - Factorial Imperative
class method StaticFiborial.FactorialI(n: integer): BigInteger;
var 
    res: BigInteger := 1;
begin
    for i:integer := n downto 1 step 1 do
        res := res * i;
    result := res;
end;
// Static/Class Method - Fibonacci Recursive
class method StaticFiborial.FibonacciR(n: integer): Int64;
begin
    if n < 2 then
        result := 1
    else
        result := FibonacciR(n - 1) + FibonacciR(n - 2);    
end;
// Static/Class Method - Fibonacci Imperative
class method StaticFiborial.FibonacciI(n: integer): Int64;
var
    tmp, pre, cur: Int64;        
begin    
    tmp := 0;
    pre := 1;
    cur := 1;
    for i: integer := 2 to n step 1 do
    begin
        tmp := cur + pre;
        pre := cur;
        cur := tmp;
    end;
    result := cur;
end;
// Static Method - Benchmarking Algorithms
class method StaticFiborial.BenchmarkAlgorithm(algorithm: integer; values: List<integer>);
var
    timer: StopWatch;
    i, testValue: integer;
    facTimeResult: BigInteger := 0;
    fibTimeResult: Int64 := 0;
begin
    i := 0;
    testValue := 0;
    timer := new StopWatch();
    // 'switch/case' Flow Constrol Statement 
    case algorithm of  
        1: begin
            Console.WriteLine(''#10'Factorial Imperative:');
            // 'For' Loop Statement
            for i := 0 to values.Count - 1 step 1 do
            begin
                testValue := values[i];
                // Taking Time    
                timer.Start();    
                facTimeResult := FactorialI(testValue);
                timer.Stop();                            
                // Getting Time    
                Console.WriteLine(' ({0}) = {1}', testValue, timer.Elapsed);
            end;
        end;
        2: begin
            Console.WriteLine(''#10'Factorial Recursive:');
            // 'While' Loop Statement 
            while i < values.Count do 
            begin
                testValue := values[i];
                // Taking Time    
                timer.Start();    
                facTimeResult := FactorialR(testValue);
                timer.Stop();                            
                // Getting Time    
                Console.WriteLine(' ({0}) = {1}', testValue, timer.Elapsed);
                inc(i);
            end;
        end;
        3: begin
            Console.WriteLine(''#10'Fibonacci Imperative:');
            // 'Repeat/Do' Loop Statement
            repeat        
                testValue := values[i];
                // Taking Time    
                timer.Start();    
                facTimeResult := FibonacciI(testValue);
                timer.Stop();
                // Getting Time    
                Console.WriteLine(' ({0}) = {1}', testValue, timer.Elapsed);
                inc(i);
            until i = values.Count - 1
        end;
        4: begin            
            Console.WriteLine(''#10'Fibonacci Recursive:');
            // 'For Each' Loop Statement
            for each item in values do
            begin
                testValue := item;  
                // Taking Time    
                timer.Start();    
                facTimeResult := FibonacciR(testValue);
                timer.Stop();
                // Getting Time    
                Console.WriteLine(' ({0}) = {1}', testValue, timer.Elapsed);
            end;
        end;
        else Console.WriteLine('DONG!');
    end;  
end;

// Instance Constructor   
constructor InstanceFiborial;
begin
    self.fClassName := 'Instance Constructor';
    Console.WriteLine(self.fClassName);
end;
// Instance Method - Factorial Recursive
method InstanceFiborial.FactorialR(n: integer): BigInteger;
begin
    // Calling Static Method    
    result := StaticFiborial.FactorialR(n);
end;
// Instance Method - Factorial Imperative
method InstanceFiborial.FactorialI(n: integer): BigInteger;
begin
    // Calling Static Method    
    result := StaticFiborial.FactorialI(n);
end;
// Instance Method - Fibonacci Recursive
method InstanceFiborial.FibonacciR(n: integer): Int64;
begin
    // Calling Static Method
    result := StaticFiborial.FibonacciR(n);
end;
// Instance Method - Fibonacci Imperative
method InstanceFiborial.FibonacciI(n: integer): Int64;
begin        
    // Calling Static Method
    result := StaticFiborial.FibonacciI(n);
end;

class method ConsoleApp.Main(args: array of string);
var
    values: List<integer>;
    ff: InstanceFiborial; 
begin
    Console.WriteLine(''#10'Static Class');
    // Calling Static Class and Methods  
    // No instantiation needed. Calling method directly from the class  
    Console.WriteLine('FacImp(5) = {0}', StaticFiborial.FactorialI(5));  
    Console.WriteLine('FacRec(5) = {0}', StaticFiborial.FactorialR(5));  
    Console.WriteLine('FibImp(11)= {0}', StaticFiborial.FibonacciI(11));  
    Console.WriteLine('FibRec(11)= {0}', StaticFiborial.FibonacciR(11));  
  
    Console.WriteLine(''#10'Instance Class');  
    // Calling Instance Class and Methods   
    // Need to instantiate before using. Calling method from instantiated object  
    ff := new InstanceFiborial();  
    Console.WriteLine('FacImp(5) = {0}', ff.FactorialI(5));  
    Console.WriteLine('FacRec(5) = {0}', ff.FactorialR(5));  
    Console.WriteLine('FibImp(11)= {0}', ff.FibonacciI(11));  
    Console.WriteLine('FibRec(11)= {0}', ff.FibonacciR(11));  
  
    // Create a (generic) list of integer values to test  
    // From 5 to 50 by 5  
    values := new List<integer>();  
    for i:integer := 5 to 50 step 5 do
        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  
    Console.Read();  
end;

end.

And the Output is:

































Humm, looks like Fibonnaci's algorithm implemented using recursion is definitively more complex than the others 3 right? I will grab these results for this and each of the upcoming posts to prepare a comparison of time execution between all the programming languages, then we will be able to talk about the algorithm's complexity as well.

Printing the Factorial and Fibonacci Series
namespace FiborialSeries;

interface
uses
    System,
    System.Text,
    System.Numerics;

type
    Fiborial = static class
    public
        class method GetFactorialSeries(n: integer): string;
        class method GetFibonnaciSeries(n: integer): string;
        class method Factorial(n: integer): BigInteger;
        class method Fibonacci(n: integer): Int64;
    end;

type
    ConsoleApp = class
    public
        class method Main(args: array of string);
    end;

implementation

class method Fiborial.GetFactorialSeries(n: integer): string;
var
    // Using a StringBuilder as a list of string elements    
    series: StringBuilder;
begin
    // Create the String that will hold the list
    series := new 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: integer := n downto 1 do
    begin
        // and append it to the list
        series.Append(i);
        if i > 1 then
            series.Append(' * ')
        else 
            series.Append(' = ');         
    end;
    // Get the result from the Factorial Method
    // and append it to the end of the list
    series.Append(Factorial(n));
    // return the list as a string
    result := series.ToString();
end;

class method Fiborial.GetFibonnaciSeries(n: integer): string;
var
    // Using a StringBuilder as a list of string elements
    series: StringBuilder;
begin
    // Create the String that will hold the list
    series := new 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: integer := 2 to n do
    begin
        if i < n then
            series.Append(', ')
        else
            series.Append(' = ');
                
        series.Append(Fibonacci(i));
    end;
    // return the list as a string
    result := series.ToString();
end;

class method Fiborial.Factorial(n: integer): BigInteger;
begin
    if n = 1 then 
        result := 1
    else 
        result := n * Factorial(n - 1);
end;

class method Fiborial.Fibonacci(n: integer): Int64;
begin
    if n < 2 then
        result := 1
    else
        result := Fibonacci(n - 1) + Fibonacci(n - 2);    
end;

class method ConsoleApp.Main(args: array of string);
begin
    // Printing Factorial Series
    Console.WriteLine();
    Console.WriteLine(Fiborial.GetFactorialSeries(5));
    Console.WriteLine(Fiborial.GetFactorialSeries(7));
    Console.WriteLine(Fiborial.GetFactorialSeries(9));
    Console.WriteLine(Fiborial.GetFactorialSeries(11));
    Console.WriteLine(Fiborial.GetFactorialSeries(40));
    // Printing Fibonacci Series
    Console.WriteLine();
    Console.WriteLine(Fiborial.GetFibonnaciSeries(5));
    Console.WriteLine(Fiborial.GetFibonnaciSeries(7));
    Console.WriteLine(Fiborial.GetFibonnaciSeries(9));
    Console.WriteLine(Fiborial.GetFibonnaciSeries(11));
    Console.WriteLine(Fiborial.GetFibonnaciSeries(40));
    Console.Read();
end;

end.

And the Output is:

















Mixing Instance and Static Members in the same Class

We can also define instance classes that have both, instance and static members such as: fields, properties, constructors, methods, etc. However, we cannot do that if the class is marked as static because of the features mentioned in the previous post:
The main features of a static class are:
  • They only contain static members.
  • They cannot be instantiated.
  • They are sealed.
  • They cannot contain Instance Constructors

namespace FiborialExtrasDelphi2;
// Instance Classes can have both: static and instance members. 
// However, Static Classes only allow static members to be defined.
// If you declare our next example class as static
// (static class Fiborial) you will get the following compile error
// Error: cannot declare instance members in a static class
interface

// Instance Class
type Fiborial = class
    private
        // Instance Field
        var fInstanceCount: integer;
        // Static Field
        class var fStaticCount: integer;
    public
        // Instance Read-Only Property   
        // Within instance members, you can always use  
        // the "this" reference pointer to access your (instance) members.     
        property InstanceCount : integer read self.fInstanceCount;
        // Static Read-Only Property     
        // Remeber that Properties are Methods to the CLR, so, you can also
        // define static properties for static fields. 
        // As with Static Methods, you cannot reference your class members
        // with the "this" reference pointer since static members are not
        // instantiated.          
        class property StaticCount : integer read fStaticCount;
        // Instance Constructor
        constructor;
        // Static Constructor
        class constructor;
        // Instance Method
        method Factorial(n: integer);
        // Static Method
        class method Fibonacci(n: integer);
    end;

type ConsoleApp = class
    public
        class method Main(args: array of string);
    end;

implementation

// Instance Constructor   
constructor Fiborial;
begin
    self.fInstanceCount := 0;
    Console.WriteLine(''#10'Instance Constructor {0}', self.fInstanceCount);
end;
// Static/Class Constructor   
class constructor Fiborial;
begin
    fStaticCount := 0;
    Console.WriteLine(''#10'Static Constructor {0}', fStaticCount);
end;
// Instance Method
method Fiborial.Factorial(n: integer);
begin
    inc(self.fInstanceCount);
    Console.WriteLine(''#10'Factorial({0})', n);
end;
// Static Method
class method Fiborial.Fibonacci(n: integer);
begin
    inc(fStaticCount);
    Console.WriteLine(''#10'Fibonacci({0})', n);
end;

class method ConsoleApp.Main(args: array of string);
begin
    // Calling Static Constructor and Methods
    // No need to instantiate
    Fiborial.Fibonacci(5);

    // Calling Instance Constructor and Methods
    // Instance required
    var fib := new Fiborial();
    fib.Factorial(5);            

    Fiborial.Fibonacci(15);            
    fib.Factorial(5);

    // Calling Instance Constructor and Methods
    // for a second object
    var fib2 := new Fiborial();
    fib2.Factorial(5);
            
    Console.WriteLine();
    // Calling Static Property
    Console.WriteLine('Static Count = {0}', Fiborial.StaticCount);
    // Calling Instance Property of object 1 and 2
    Console.WriteLine('Instance 1 Count = {0}', fib.InstanceCount);
    Console.WriteLine('Instance 2 Count = {0}', fib2.InstanceCount);
    Console.Read();
end;

end.

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 on my previous post in VB.NET that I realized about this faulty code, because instead of giving me a wrong value, VB.NET execution thrown an Overflow Exception when using the "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.

namespace FiborialExtrasDelphi3;

interface

uses   
    System,
    System.Numerics,
    System.Diagnostics;

type
    ConsoleApp = class
    public
        class method Main(args: array of string);
        class method FactorialInt64(n: integer): Int64;
        class method FactorialDouble(n: integer): Double;
        class method FactorialBigInteger(n: integer): BigInteger;
    end;

implementation

class method ConsoleApp.Main(args: array of string);
var
    timer: StopWatch;
    facIntResult: System.Int64 := 0;
    facDblResult: System.Double := 0;
    facBigResult: System.Numerics.BigInteger := 0;

begin
    timer := new StopWatch();
    Console.WriteLine(''#10'Factorial using Int64');    
    for i: integer := 5 to 50 step 5 do
    begin                
        timer.Start();
        facIntResult := FactorialInt64(i);
        timer.Stop();                                    
        Console.WriteLine(' ({0}) = {1} : {2}', i, timer.Elapsed, facIntResult);
    end;
    Console.WriteLine(''#10'Factorial using Double');
    for i: integer := 5 to 50 step 5 do
    begin                
        timer.Start();
        facDblResult := FactorialDouble(i);
        timer.Stop();                                    
        Console.WriteLine(' ({0}) = {1} : {2}', i, timer.Elapsed, facDblResult);
    end;
    Console.WriteLine(''#10'Factorial using BigInteger');
    for i: integer := 5 to 50 step 5 do
    begin                
        timer.Start();
        facBigResult := FactorialBigInteger(i);
        timer.Stop();                                    
        Console.WriteLine(' ({0}) = {1} : {2}', i, timer.Elapsed, facBigResult);
    end;
    Console.Read();
end;

class method ConsoleApp.FactorialInt64(n: integer): Int64;
begin
    if n = 1 then 
        result := 1
    else 
        result := n * FactorialInt64(n - 1);
end;

class method ConsoleApp.FactorialDouble(n: integer): Double;
begin
    if n = 1 then 
        result := 1
    else 
        result := n * FactorialDouble(n - 1);
end;

class method ConsoleApp.FactorialBigInteger(n: integer): BigInteger;
begin
    if n = 1 then 
        result := 1
    else 
        result := n * FactorialBigInteger(n - 1);
end;

end.

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:

Monday, November 1, 2010

Oxygene - Basics by Example



Continue with the Basics by Example; today's version of the post written in Oxygene 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
// Delphi Prism Basics
namespace DPGreetProgram;  

interface
uses
    System;   
  
type 
    Greet = public class      
        // Fields of Attributes
        private var fMessage: String;            
        private var fName: String;
        private var fLoopMessage: Integer;
        // Methods Definition
        private method Capitalize(value: String): String;
        private method SetMessage(value: String);
        private method SetName(value: String);    
        // Properties
        public property Message: String read fMessage write SetMessage;
        public property Name: String read fName write SetName;
        public property LoopMessage: Integer read fLoopMessage write fLoopMessage;        
        // Constructors Definition
        public constructor();
        public constructor(message: String; name: String; loopMessage: Integer);  
        // Methods Definition
        public method Salute();
        public method Salute(message: String; name: String; loopMessage: Integer);  
        public method Salute(name: String);
    end;  
  
type  
    GreetProgram = public class      
    public class method Main(args: array of String);  
    end;

implementation
// Property Setters/Getters Methods
method Greet.SetMessage(value: String);
begin
    self.fMessage := self.Capitalize(value);
end;
method Greet.SetName(value: String);
begin
    self.fName := self.Capitalize(value);
end;
// Constructor 
constructor Greet();
begin
    self.fMessage := "";
    self.fName := "";
    self.loopMessage := 0;    
end;  
// Overloaded Constructor 
constructor Greet(message: String; name: String; loopMessage: Integer);
begin
    self.fMessage := message;
    self.fName := name;
    self.loopMessage := loopMessage;
end;
// Method 1
method Greet.Capitalize(value: String): String;
begin
    // "if-then-else" statement 
    if value.Length >= 1 then 
    begin
        result := value[0].ToString().ToUpper() + value.SubString(1, value.Length - 1);
    end
    else 
    begin
        result := "";
    end;
end;
// Method 2
method Greet.Salute();
begin  
    // "for" statement 
    for i: Integer := 1 to self.loopMessage step 1 do
    begin
        Console.WriteLine("{0} {1}!", self.fMessage, self.fName);
    end;
end;  
// Overloaded Method 2.1 
method Greet.Salute(message: String; name: String; loopMessage: Integer);
var
    i: Integer;
begin
    // "while" statement  
    i := 0;
    while i < loopMessage do 
    begin
        Console.WriteLine("{0} {1}!", self.Capitalize(message), self.Capitalize(name));
        i := i + 1;
    end;
end;
// Overloaded Method 2.2  
method Greet.Salute(name: String);
var    
    dtNow: DateTime;
begin
    // "switch/case" statement  
    dtNow := DateTime.Now;
    case dtNow.hour of
        6..11: self.fMessage := "good morning,";
        12..17: self.fMessage := "good afternoon,";
        18..22: self.fMessage := "good evening,";
        23,0..5: self.fMessage := "good night,";
        else self.fMessage := "huh?"; 
    end;
    Console.WriteLine("{0} {1}!", self.Capitalize(self.fMessage), self.Capitalize(name));
end;

// Console Program
class method GreetProgram.Main(args: array of String);  
var
    // Define object of type Greet    
    g: Greet;
begin  
    // Instantiate Greet. Call Constructor 
    g := new Greet();
    // Call Set Properties  
    g.Message := "hello";  
    g.Name := "world";  
    g.LoopMessage := 5;  
    // Call Method 2  
    g.Salute();  
    // Call Overloaded Method 2.1 and Get Properties  
    g.Salute(g.Message, "delphi Prism", g.LoopMessage);  
    // Call Overloaded Method 2.2  
    g.Salute("carlos");
    
    // Stop and exit  
    Console.WriteLine("Press any key to exit...");  
    Console.Read();  
end;  
end.


Greetings Program - Minimal
// Delphi Prism Basics
namespace;

interface
uses
    System;   
  
type
    Greet = class  
    private
        // Fields of Attributes
        fMessage: String;
        fName: String;
        fLoopMessage: Integer;
        // Methods Definition
        method Capitalize(value: String): String;
        method SetMessage(value: String);
        method SetName(value: String);
    public
        // Properties
        property Message: String read fMessage write SetMessage;
        property Name: String read fName write SetName;
        property LoopMessage: Integer read fLoopMessage write fLoopMessage;        
        // Constructors Definition
        constructor;
        constructor(message: String; name: String; loopMessage: Integer);  
        // Methods Definition
        method Salute;
        method Salute(message: String; name: String; loopMessage: Integer);  
        method Salute(name: String);
    end;  
  
type 
    GreetProgram = class
    public  
        class method Main(args: array of String);  
    end;

implementation
// Property Setters/Getters Methods
method Greet.SetMessage(value: String);
begin
    fMessage := Capitalize(value);
end;
method Greet.SetName(value: String);
begin
    fName := Capitalize(value);
end;
// Constructor 
constructor Greet;
begin
    fMessage := "";
    fName := "";
    loopMessage := 0;    
end;  
// Overloaded Constructor 
constructor Greet(message: String; name: String; loopMessage: Integer);
begin
    fMessage := message;
    fName := name;
    loopMessage := loopMessage;
end;
// Method 1
method Greet.Capitalize(value: String): String;
begin
    // "if-then-else" statement 
    if value.Length >= 1 then 
    begin
        result := value[0].ToString().ToUpper() + value.SubString(1, value.Length - 1);
    end
    else 
    begin
        result := "";
    end;
end;
// Method 2
method Greet.Salute;
begin  
    // "for" statement 
    for i: Integer := 1 to loopMessage step 1 do
    begin
        Console.WriteLine("{0} {1}!", fMessage, fName);
    end;
end;  
// Overloaded Method 2.1 
method Greet.Salute(message: String; name: String; loopMessage: Integer);
var
    i: Integer;
begin
    // "while" statement  
    i := 0;
    while i < loopMessage do 
    begin
        Console.WriteLine("{0} {1}!", Capitalize(message), Capitalize(name));
        i := i + 1;
    end;
end;
// Overloaded Method 2.2  
method Greet.Salute(name: String);
var    
    dtNow: DateTime;
begin
    // "switch/case" statement  
    dtNow := DateTime.Now;
    case dtNow.hour of
        6..11: fMessage := "good morning,";
        12..17: fMessage := "good afternoon,";
        18..22: fMessage := "good evening,";
        23,0..5: fMessage := "good night,";
        else fMessage := "huh?"; 
    end;
    Console.WriteLine("{0} {1}!", Capitalize(fMessage), Capitalize(name));
end;

// Console Program
class method GreetProgram.Main(args: array of String);  
var
    // Define object of type Greet    
    g: Greet;
begin  
    // Instantiate Greet. Call Constructor 
    g := new Greet();
    // Call Set Properties  
    g.Message := "hello";  
    g.Name := "world";  
    g.LoopMessage := 5;  
    // Call Method 2  
    g.Salute;
    // Call Overloaded Method 2.1 and Get Properties  
    g.Salute(g.Message, "delphi Prism", g.LoopMessage);  
    // Call Overloaded Method 2.2      
    g.Salute("carlos");    
    // Stop and exit  
    Console.WriteLine("Press any key to exit...");  
    Console.Read();  
end;  
end.

And the Output is:





















Auto-Implemented Properties in Delphi Prism
Auto-implemented properties enable you to quickly specify a property of a class without having to write code to Get and Set the property. The following code shows how to use them just like with VB.NET, C#, C++/CLI and so on.

namespace;
interface
uses System;   

type Greet = class  
    // No explicit private field required
    // private fMessage: String;
    // Auto Implemented Property
    property Message: String;
    constructor();        
    method Salute();        
    method Salute(value: String);
end;  

type GreetProgram = class
    class method Main(args: array of String);  
end;

implementation
// Constructor 
constructor Greet();
begin
    Message := "";
end;  
method Greet.Salute();
begin  
    Console.WriteLine(Message[0].ToString().ToUpper() + Message.SubString(1, Message.Length - 1));
end;  
method Greet.Salute(value: String);
begin  
    Console.WriteLine(value[0].ToString().ToUpper() + value.SubString(1, value.Length - 1));
end; 

class method GreetProgram.Main(args: array of String);  
var g: Greet;
begin  
    g := new Greet();
    // Call Set Auto Implemented Property
    g.Message := "hello";  
    g.Salute;
    g.Message := "bye";
    // Call Get Auto Implemented Property
    g.Salute(g.Message);
end;  
end.


And the Output is: