Saturday, January 29, 2011

Factorial and Fibonacci in C#



UPDATE: updated code examples and section using System.Numerics.BigInteger.

Here below a little program in C# 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 C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;

namespace FiborialCs
{
    // Static Class
    static class StaticFiborial
    {
        // Static Field
        static string className;
        // Static Constructor
        static StaticFiborial()
        {
            className = "Static Constructor";
            Console.WriteLine(className);            
        }
        // Static Method - Factorial Recursive
        public static BigInteger FactorialR(int n)
        {
            if (n == 1)
                return 1;
            else
                return n * FactorialR(n - 1);
        }
        // Static Method - Factorial Imperative
        public static BigInteger FactorialI(int n)
        {
            BigInteger res = 1;
            for (int i = n; i >= 1; i--)
            {                
                res *= i;
            }
            return res;
        }
        // Static Method - Fibonacci Recursive
        public static long FibonacciR(int n)
        {
            if (n < 2)
                return 1;
            else
                return FibonacciR(n - 1) + FibonacciR(n - 2);
        }
        // Static Method - Fibonacci Imperative
        public static long FibonacciI(int n)
        {            
            long pre, cur, tmp = 0;
            pre = cur = 1;            
            for (int i = 2; i <= n; i++)
            {
                tmp = cur + pre;
                pre = cur;
                cur = tmp;
            }
            return cur;
        }
        // Static Method - Benchmarking Algorithms
        public static void BenchmarkAlgorithm(int algorithm, List<int> values)
        {            
            Stopwatch timer = new Stopwatch();
            int i, testValue;
            BigInteger facTimeResult = 0;
            long fibTimeResult = 0;
            i = testValue = 0;            
            
            // "Switch" Flow Constrol Statement
            switch (algorithm)
            {
                case 1:
                    Console.WriteLine("\nFactorial Imperative:");
                    // "For" Loop Statement
                    for (i = 0; i < values.Count; i++)
                    {                        
                        testValue = values[i];
                        // Taking Time
                        timer.Start();
                        facTimeResult = FactorialI(testValue);
                        timer.Stop();                        
                        // Getting Time
                        Console.WriteLine(" ({0}) = {1}", testValue, timer.Elapsed);
                    }                    
                    break;
                case 2:
                    Console.WriteLine("\nFactorial Recursive:");
                    // "While" Loop Statement
                    while (i < values.Count)
                    {                        
                        testValue = values[i];
                        // Taking Time
                        timer.Start();
                        facTimeResult = FactorialR(testValue);
                        timer.Stop();
                        // Getting Time
                        Console.WriteLine(" ({0}) = {1}", testValue, timer.Elapsed);
                        i++;
                    }
                    break;
                case 3:
                    Console.WriteLine("\nFibonacci Imperative:");
                    // "Do-While" Loop Statement
                    do {
                        testValue = values[i];
                        // Taking Time
                        timer.Start();
                        fibTimeResult = FibonacciI(testValue);
                        timer.Stop();
                        // Getting Time
                        Console.WriteLine(" ({0}) = {1}", testValue, timer.Elapsed);
                        i++;
                    } while (i < values.Count);
                    break;
                case 4:
                    Console.WriteLine("\nFibonacci Recursive:");
                    // "For Each" Loop Statement
                    foreach (int item in values)
                    {
                        testValue = item;
                        // Taking Time
                        timer.Start();
                        fibTimeResult = FibonacciR(testValue);
                        timer.Stop();
                        // Getting Time
                        Console.WriteLine(" ({0}) = {1}", testValue, timer.Elapsed);
                    }
                    break;
                default:
                    Console.WriteLine("DONG!");
                    break;
            }                
        }
    }

    // Instance Class
    public class InstanceFiborial
    {
        // Instance Field
        string className;
        // Instance Constructor
        public InstanceFiborial()
        {
            this.className = "Instance Constructor";
            Console.WriteLine(this.className);
        }
        // Instance Method - Factorial Recursive
        public BigInteger FactorialR(int n)
        {
            // Calling Static Method
            return StaticFiborial.FactorialR(n);
        }
        // Instance Method - Factorial Imperative
        public BigInteger FactorialI(int n)
        {
            // Calling Static Method
            return StaticFiborial.FactorialI(n);
        }
        // Instance Method - Fibonacci Recursive
        public long FibonacciR(int n)
        {
            // Calling Static Method
            return StaticFiborial.FibonacciR(n);
        }
        // Instance Method - Factorial Imperative
        public long FibonacciI(int n)
        {
            // Calling Static Method
            return StaticFiborial.FibonacciI(n);
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\nStatic 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("\nInstance Class");
            // Calling Instance Class and Methods 
            // Need to instantiate before using. Calling method from instantiated object
            InstanceFiborial 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
            List<int> values = new List<int>();
            for(int 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
            Console.Read();
        }
    }
}

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
using System;
using System.Text;
using System.Numerics;

namespace FiborialSeries
{    
    static class Fiborial
    {
        // Using a StringBuilder as a list of string elements
        public static string GetFactorialSeries(int n)
        {
            // Create the String that will hold the list
            StringBuilder 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 (int 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(Factorial(n));
            // return the list as a string
            return series.ToString();
        }

        // Using a StringBuilder as a list of string elements
        public static string GetFibonnaciSeries(int n)
        {
            // Create the String that will hold the list
            StringBuilder 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 (int i = 2; i <= n; i++)
            {
                if (i < n)
                    series.Append(", ");
                else
                    series.Append(" = ");
                
                series.Append(Fibonacci(i));
            }
            // return the list as a string
            return series.ToString();
        }

        public static BigInteger Factorial(int n)
        {
            if (n == 1)
                return 1;
            else
                return n * Factorial(n - 1);
        }

        public static long Fibonacci(int n)
        {
            if (n < 2)
                return 1;
            else
                return Fibonacci(n - 1) + Fibonacci(n - 2);
        }
        
    }

    class Program
    {
        static void Main(string[] args)
        {            
            // 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));
        }
    }
}

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

using System;
namespace FiborialExtrasCs2
{
    // 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
    
    // Instance Class
    class Fiborial
    {
        // Instance Field
        private int instanceCount;
        // Static Field
        private static int staticCount;        
        // Instance Read-Only Property
        // Within instance members, you can always use  
        // the "this" reference pointer to access your (instance) members.
        public int InstanceCount
        {
            get { return this.instanceCount; }
        }
        // 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.        
        public static int StaticCount
        {
            get { return staticCount; }
        }
        // Instance Constructor
        public Fiborial()
        {
            this.instanceCount = 0;
            Console.WriteLine("\nInstance Constructor {0}", this.instanceCount);
        }
        // Static Constructor
        static Fiborial()
        {
            staticCount = 0;
            Console.WriteLine("\nStatic Constructor {0}", staticCount);
        }

        // Instance Method
        public void Factorial(int n)
        {
            this.instanceCount += 1;
            Console.WriteLine("\nFactorial({0})", n);
        }

        // Static Method
        public static void Fibonacci(int n)
        {
            staticCount += 1;
            Console.WriteLine("\nFibonacci({0})", n);
        }                
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            // Calling Static Constructor and Methods
            // No need to instantiate
            Fiborial.Fibonacci(5);            

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

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

            // Calling Instance Constructor and Methods
            // for a second object
            Fiborial 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);
        }
    }
}

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

using System;
using System.Numerics;
using System.Diagnostics;

namespace FiborialExtrasCs3
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            System.Int64 facIntResult = 0;
            System.Double facDblResult = 0;
            System.Numerics.BigInteger facBigResult = 0;

            Console.WriteLine("\nFactorial using Int64");
            // Benchmark Factorial using Int64
            for (int i = 5; i <= 50; i += 5)
            {
                timer.Start();
                facIntResult = FactorialInt64(i);
                timer.Stop();
                Console.WriteLine(" ({0}) = {1} : {2}", i, timer.Elapsed, facIntResult);
            }
            Console.WriteLine("\nFactorial using Double");
            // Benchmark Factorial using Double
            for (int i = 5; i <= 50; i += 5)
            {
                timer.Start();
                facDblResult = FactorialDouble(i);
                timer.Stop();
                Console.WriteLine(" ({0}) = {1} : {2}", i, timer.Elapsed, facDblResult);
            }
            Console.WriteLine("\nFactorial using BigInteger");
            // Benchmark Factorial using BigInteger
            for (int i = 5; i <= 50; i += 5)
            {
                timer.Start();
                facBigResult = FactorialBigInteger(i);
                timer.Stop();
                Console.WriteLine(" ({0}) = {1} : {2}", i, timer.Elapsed, facBigResult);
            }
        }

        // Long Factorial 
        public static Int64 FactorialInt64(int n)
        {
            if (n == 1)
                return 1;
            else
                return n * FactorialInt64(n - 1);
        }

        // Double Factorial 
        public static Double FactorialDouble(int n)
        {
            if (n == 1)
                return 1;
            else
                return n * FactorialDouble(n - 1);
        }
        
        // BigInteger Factorial 
        public static BigInteger FactorialBigInteger(int n)
        {
            if (n == 1)
                return 1;
            else
                return n * FactorialBigInteger(n - 1);
        }
    }
}

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

And the Output is:

Tuesday, January 25, 2011

New Series - Factorial and Fibonacci


I'm going to start a new series of posts called "Factorial and Fibonacci in [Language]". As with my previous 2 series, "OO Hello World" and "Language's Basics by Example", my aim is to show programming language's basic features, and as such, I will be showing stuff such as: static members, instance member, recursion, more loops and conditional constructs, and whatever else comes up. The idea is to write a simple OO program that implements the Factorial and Fibonacci algorithms in a Functional (Recursion) and Imperative (Statements-Loops) way using static methods and fields plus different loop statements such as Do, While, For, For each, etc. I will also add the Timer classes provided by the language's framework to count how much time those algorithms take (benchmark?) and do some comparison of the timing by language.

From now on, I will not be including 2 versions of the same program. First, to save some space and second, because counting keywords is not the main topic anymore. So, a mix of minimal and verbose syntax in each of the languages will be used instead.

The languages:
.NET/CLR: C#, VB.NET, C++/CLI, F#, Boo, Phalanger, IronPython, IronRuby, Delphi Prism, Zonnon, Nemerle, Cobra, JScript.NET
Java/JVM: Groovy, Java, Jython, JRuby, Fantom, Scala, JavaFX, Gosu


The Program's Structure will be (more or less) as follows:
// Factorial and Fibonacci in Language
    // Static Class
        // Static Fields
        // Static Constructor
        // Static Method 1
            // Recursive Fibonacci
        // Static Method 2
            // Imperative Fibonacci
        // Static Method 3
            // Recursive Factorial
        // Static Method 4
            // Imperative Factorial
        // Static Method 5
            // For Loop Range
                // Start Timer
                // Call Static Method: Recursive Fibonacci
                // Stop Timer
                // Print Result
            // While Loop Range
                // Start Timer
                // Call Static Method: Imperative Fibonacci
                // Stop Timer
                // Print Result
            // Do Loop Range
                // Start Timer
                // Call Static Method: Recursive Factorial
                // Stop Timer
                // Print Result
            // For Each Loop Range
                // Start Timer
                // Call Static Method: Imperative Factorial
                // Stop Timer
                // Print Result

    // Instance Class
        // Instance Fields
        // Instance Constructor
        // Instance Method 1
            // Call Static Recursive Fibonacci
        // Instance Method 2
            // Call Static Imperative Fibonacci
        // Instance Method 3
            // Call Static Recursive Factorial
        // Instance Method 4
            // Call Static Imperative Factorial

    // Console Program/Script
        // Calling Static Class and Methods
        // Calling Instance Class and Methods
        // Create a List of values to test
        // Benchmarking Fibonacci
        // Call Factorial Imperative
        // Call Factorial Recursive
        // Benchmarking Factorial
        // Call Fibonacci Imperative
        // Call Fibonacci Recursive
        // Stop and exit


And here below some definitions of the new concepts:

Factorial
"In mathematics, the factorial of a positive integer n,[1] denoted by n!, is the product of all positive integers less than or equal to n. For example:

5! = 5 x 4 x 3 x 2 x 1 = 120

0! is a special case that is explicitly defined to be 1."
Taken from: http://en.wikipedia.org/wiki/Factorial#Definition

Fibonacci
"In mathematics, the Fibonacci numbers are the numbers in the following integer sequence:

0,1,1,2,3,5,8,13,21,34,55,89,144, ...

By definition, the first two Fibonacci numbers are 0 and 1, and each subsequent number is the sum of the previous two. Some sources omit the initial 0, instead beginning the sequence with two 1s." Taken from: http://en.wikipedia.org/wiki/Fibonacci_series

Recursion
"Recursion is the process of repeating items in a self-similar way. For instance, when the surfaces of two mirrors are exactly parallel with each other the nested images that occur are a form of infinite recursion. The term has a variety of meanings specific to a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in mathematics and computer science, in which it refers to a method of defining functions in which the function being defined is applied within its own definition; specifically it is defining an infinite statement using finite components." Taken from: http://en.wikipedia.org/wiki/Recursion

Imperative
"In computer science, imperative programming is a programming paradigm that describes computation in terms of statements that change a program state. In much the same way that imperative mood in natural languages expresses commands to take action, imperative programs define sequences of commands for the computer to perform." Taken from: http://en.wikipedia.org/wiki/Imperative_programming

Static Class
"A class can be declared static, indicating that it contains only static members. It is not possible to create instances of a static class using the new keyword.

Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.

  • 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 (C# Programming Guide).

Creating a static class is therefore much the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated.

The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.

Static classes are sealed and therefore cannot be inherited. Static classes cannot contain a constructor, although it is still possible to declare a static constructor to assign initial values or set up some static state." Taken from: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx

Static Variable
"In computer programming, a static variable is a variable that has been allocated statically — whose lifetime extends across the entire run of the program. This is in contrast to the more ephemeral automatic variables (local variables), whose storage is allocated and deallocated on the call stack; and in contrast to objects whose storage is dynamically allocated." Taken from: http://en.wikipedia.org/wiki/Static_variable#Static_Variables_as_Class_Variables

Static Method
"In object-oriented programming, a method is a subroutine that is exclusively associated either with a class (in which case it is called a class method or a static method) or with an object (in which case it is an instance method).

As mentioned above, a method may be declared as static, meaning that it acts at the class level rather than at the instance level. Therefore, a static method cannot refer to a specific instance of the class (i.e. it cannot refer to this, self, Me, etc.), unless such references are made through a parameter referencing an instance of the class, although in such cases they must be accessed through the parameter's identifier instead of this. Most importantly there is no need to make an object for accessing data .i.e. without creating an object we can access the data members of a static class." Taken from: http://en.wikipedia.org/wiki/Static_method#Static_methods

Static Constructor
"A static constructor is a static data initializer. Static constructors allow complex static variable initialization.[1] Static constructors can be called once and call is made implicitly by the run-time right before the first time the class is accessed. Any call to a class (static or constructor call), triggers the static constructor execution. Static constructors are thread safe and are a great way to implement a singleton pattern. When used in a generic programming class, static constructors are called on every new generic instantiation one per type (static variables are instantiated as well)." Taken from:http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#C.23_static_constructor

Benchmark
"In computing, a benchmark is the act of running a computer program, a set of programs, or other operations, in order to assess the relative performance of an object, normally by running a number of standard tests and trials against it. The term 'benchmark' is also mostly utilized for the purposes of elaborately-designed benchmarking programs themselves." Taken from: http://en.wikipedia.org/wiki/Benchmark_(computing)


return;

Saturday, January 15, 2011

Counting Source Code Keywords using Python 3



Now that I finished my last post about counting keywords in source code, I will give away the little script I did to help me with the counting. It definitively requires some improvements to cover some extra cases I did not consider, but it work just fine if you manage to avoid them... or even better, implement them yourself :D

1. Multi-line comments are not supported. If there are reserved words within the comments, they will be counted as keywords. But worry not; single line comments work fine.

2. Text literals are not supported. If there are reserved words within the string, they will be counted as keywords.

I think regular expressions can handle those 2 cases. I'll add those two features if I need them in the future.

The programming language used was Python version 3.1.3

I formatted some parts of the code to correctly display it using the size limit of this blog's page. For instance, if the script doesn't compile; try using one line comma separated lists and if statements.

I think the code is simple and very easy to read... that's what all programmers say about their own code, right? Anyway, here below, I will begin by showing, function by function, the code of the script including lots of unnecessary comments and some screen shots that help explain what it does. Next, I will show a complete example of how to use it and the output.
The complete script without comments it's available at the bottom of this post.

Dissecting the Script

# import from sys to handle script's (command line) parameters
import sys
# get_line_comment_char function returns the Language's single 
# line character(s)
# only one "single comments character" is taken in consideration 
# even if the language supports multiple single line comments
# I grouped languages using the same comment character to reduce 
# the number of ifs
def get_line_comment_char(language):
    language = language.lower()    
    if language in ('c#', 'csharp', 'cpp', 'cppcli', 'c++', 'c++cli', 'f#', 
                    'fsharp', 'boo', 'phalanger', 'php', 'delphiprism', 'delphi', 
                    'nemerle', 'groovy', 'java', 'fantom', 'fan', 'jscript', 
                    'jscriptnet', 'scala', 'javafx', 'javafxscript', 'gosu'):
        return '//'
    elif language in ('vb', 'vbnet', 'visualbasic'):
        return '\''
    elif language in ('jython', 'ironpython', 'python', 'jruby', 'ironruby', 
                    'ruby', 'cobra'):
        return '#'        
    elif language in ('zonnon'):
        return '(*'
    return None

Example:



# get_language_keywords function returns a list of all the 
# keywords (reserved words) for the given language
# except for the primitive types since I didn't consider them 
# as keywords for my comparison purposes
# if you need them, you can take the complete keywords lists 
# this blog's Keywords page
# I removed the lists to save space because it makes the program
# too long and less readable, so, in the function below, 
# for every ocurrence of keywords = '' you change '' with the list 
# of keywords of that language.
def get_language_keywords(language):
    language = language.lower()    
    if language == 'c#' or language == 'csharp':
        keywords = '' 
    elif language == 'vb' or language == 'vbnet' 
        or language == 'visualbasic':        
        keywords = '' 
    elif language == 'cpp' or language == 'cppcli' 
        or language == 'c++' or language == 'c++cli':
        keywords = '' 
    elif language == 'f#' or language == 'fsharp':        
        keywords = '' 
    elif language == "boo":
        keywords = '' 
    elif language == 'phalanger' or language == 'php':
        keywords = '' 
    elif language == 'jython' or language == 'ironpython' 
        or language == 'python':        
        keywords = '' 
    elif language == 'jruby' or language == 'ironruby' 
        or language == 'ruby':
        keywords = '' 
    elif language == 'delphiprism' or language == 'delphi':
        keywords = '' 
    elif language == 'zonnon':
        keywords = '' 
    elif language == 'nemerle':
        keywords = '' 
    elif language == 'groovy':
        keywords = '' 
    elif language == 'java':
        keywords = '' 
    elif language == 'cobra':
        keywords = '' 
    elif language == 'fantom' or language == 'fan':
        keywords = '' 
    elif language == 'jscript' or language == 'jscriptnet':
        keywords = '' 
    elif language == 'scala':
        keywords = '' 
    elif language == 'javafx' or language == 'javafxscript':
        keywords = '' 
    elif language == 'gosu':
        keywords = '' 
    else:
        keywords = ''
    return keywords.split()

Example:



# is_keyword function returns true if the given keyword is a 
# valid keyword in the given language
def is_keyword(key, language_keys):    
    if key in language_keys:
        return True
    return False

Example:



# remove_special_characters function removes special characters 
# from the given text and returns the resulting sequence
# special characters includes open and closing blocks, 
# operators, and so on (see the list below).
def remove_special_characters(text):
    special_characters = ('(','[','{','}',']',')','+','-','*','/','=','^','&',
                        '%','$','#','@','!','~','\'','\"', '?', '>', '<', ':', 
                        ';', ',', '.')
    for character in special_characters:
        text = text.replace(character, ' ')
    return text

Example:



# remove_duplicates_in_list function removes any duplicate value 
# found in the given sequence and returns the resulting sequence
def remove_duplicates_in_list(sequence):
    # Thanks to Dave Kirby for this function taken from comments in 
    # http://www.peterbe.com/plog/uniqifiers-benchmark 
    seen = set()
    seen_add = seen.add
    return [x for x in sequence if x not in seen and not seen_add(x)]

Example:



# count_ocurrences_in_list function returns a new list of paired values 
# that contain the keyword and how many times it appeared in the code
# using the standard count method of the sequences types
def count_ocurrences_in_list(sequence):
    totals_by_word = []
    no_duplicates = remove_duplicates_in_list(sequence)
    for word in no_duplicates:
        totals_by_word.append((word,sequence.count(word)))
    return totals_by_word

Example:



# print_results function prints the given sequence to the console
# It displays the list of Keyword and Total Number of Keywords
def print_results(sequence):
    print('', end='\n')    
    for item in sequence:
        print('%s, %s' % (item[0], item[1]))    

Example:



# print_to_file function creates an output file and prints the given 
# sequence into it. 
# It writes the list of Keyword and Total Number of Keywords
def print_to_file(sequence, output):
    with open(output, mode='w', encoding='utf-8') as output_file:
        output_file.write('\n')
        for item in sequence:
            output_file.write('%s, %s\n' % (item[0], item[1]))

Example:

Output:

Opening CSV:




# Main function. The program's entry point.
def main(argv=None):
    # if command line arguments are not empty
    if argv is None:
        # assign them to the local sequence variable argv
        argv = sys.argv
    
    # validate the script was used correctly. 
    if len(argv) != 4:
        # Otherwise, print the usage message to the console
        print("usage: program language sourcefile outputfile")
        # and exit the script
        sys.exit()

Example:



# get command line arguments
    # parameter 2 should be the language of the source code you want to count
    programming_language = sys.argv[1]    
    # parameter 3 should be the file that contains the source code you want to count
    source_file = sys.argv[2]    
    # parameter 4 should be the file that will contain the counting results
    output_file = sys.argv[3]     
    # get the list of reserved words for the given programming language
    language_keywords = get_language_keywords(programming_language)
    # get the single line comment character for the given programming language
    comment_character = get_line_comment_char(programming_language)

Example:
Here I added some print() and exit() to stop execution of the script



# define a variable that will hold the total number of keywords found in the file
    total_keywords_found = 0
    # define a list that will store all valid language keywords found in the file
    list_of_keywords_found = []

line_number = 0
    # open a file as read only (default mode)
    with open(source_file, encoding='utf-8') as source_code:
        # navigate through the lines of the file
        for line in source_code:
            # get the line number. Used only for console display purposes
            line_number += 1

Example:
The following line adds the line number to the beginning of the line being read
print('{:>4} {}'.format(line_number, line.rstrip()), end='\n')



# remove line comment if there is one based on the 
            # language's single line comment character  
            comment_idx = line.find(comment_character)
            if comment_idx >= 0:
                line = line[0:comment_idx]

Example:



# remove special characters from remaining text in line 
            # (operators and open-close characters)
            line = remove_special_characters(line)
            # create a list with all remaining words in the line
            words = line.split()

Example:



# navigate through the words of the sequence
            for word in words:
                # if the current word is a valid keyword for the 
                # given language
                if is_keyword(word, language_keywords):                    
                    # add to the list of 
                    # "total keywords found in the source code" the word
                    list_of_keywords_found.append(word)
                    # increment the number of total words found 
                    # in the source code
                    total_keywords_found = total_keywords_found + 1

Example:



# define a list that will store all paired 
    # values (keyword and total ocurrences of that keyword)
    totals_to_output = []    
    # insert first pair of values as the first element of the list, 
    # that is the Programming Language and the Total Keywords found
    totals_to_output.append((programming_language.capitalize(),str(total_keywords_found)))
    # insert all other pairs of values (keyword and total ocurrences 
    # of that keyword) found on the source code
    totals_to_output.extend(count_ocurrences_in_list(list_of_keywords_found))

Example:



# print the results to the console
    print_results(totals_to_output)
    # print the results to the output file
    print_to_file(totals_to_output, output_file)

# run the program
if __name__ == "__main__":    
    main()

Example:















Using the Script

How to use is was already shown in the step by step example above, but here below I just show you how I did the counting for my previous post "Keywords in source code Round 2"

First I created 2 folders:
1. SrcCode
2. OutCode



















Then, I added all the source code files I wanted to count from into the SrcCode folder.























Next step was to create a batch file that runs the python script for all the files in the SrcCode folder.













And ran it







Console Output






















Files Output in folder OutCode






















Et Voilà! I then started merging together the results and did the graphs.

Hope this script works for you or at least shows you some cool python features :)


Final Script

Just don't forget to add the language keywords! take them from the Keywords Page.
Example:
keywords = 'public private static internal for if else while switch'

import sys

def get_line_comment_char(language):
    language = language.lower()    
    if language in ('c#', 'csharp', 'cpp', 'cppcli', 'c++', 'c++cli', 'f#', 
                    'fsharp', 'boo', 'phalanger', 'php', 'delphiprism', 'delphi', 
                    'nemerle', 'groovy', 'java', 'fantom', 'fan', 'jscript', 
                    'jscriptnet', 'scala', 'javafx', 'javafxscript', 'gosu'):
        return '//'
    elif language in ('vb', 'vbnet', 'visualbasic'):
        return '\''
    elif language in ('jython', 'ironpython', 'python', 'jruby', 'ironruby', 
                    'ruby', 'cobra'):
        return '#'        
    elif language in ('zonnon'):
        return '(*'
    return None

def get_language_keywords(language):
    language = language.lower()    
    if language == 'c#' or language == 'csharp':
        keywords = '' 
    elif language == 'vb' or language == 'vbnet' 
        or language == 'visualbasic':        
        keywords = '' 
    elif language == 'cpp' or language == 'cppcli' 
        or language == 'c++' or language == 'c++cli':
        keywords = '' 
    elif language == "f#" or language == "fsharp":        
        keywords = '' 
    elif language == "boo":
        keywords = '' 
    elif language == 'phalanger' or language == 'php':
        keywords = '' 
    elif language == 'jython' or language == 'ironpython' 
        or language == 'python':        
        keywords = '' 
    elif language == 'jruby' or language == 'ironruby' 
        or language == 'ruby':
        keywords = '' 
    elif language == 'delphiprism' or language == 'delphi':
        keywords = '' 
    elif language == 'zonnon':
        keywords = '' 
    elif language == 'nemerle':
        keywords = '' 
    elif language == 'groovy':
        keywords = '' 
    elif language == 'java':
        keywords = '' 
    elif language == 'cobra':
        keywords = '' 
    elif language == 'fantom' or language == 'fan':
        keywords = '' 
    elif language == 'jscript' or language == 'jscriptnet':
        keywords = '' 
    elif language == 'scala':
        keywords = '' 
    elif language == 'javafx' or language == 'javafxscript':
        keywords = '' 
    elif language == 'gosu':
        keywords = '' 
    else:
        keywords = ''
    return keywords.split()

def is_keyword(key, language_keys):    
    if key in language_keys:
        return True
    return False

def remove_special_characters(text):
    special_characters = ('(','[','{','}',']',')','+','-','*','/','=','^','&',
                        '%','$','#','@','!','~','\'','\"', '?', '>', '<', ':', 
                        ';', ',', '.')
    for character in special_characters:
        text = text.replace(character, ' ')
    return text

def remove_duplicates_in_list(sequence):
    seen = set()
    seen_add = seen.add
    return [x for x in sequence if x not in seen and not seen_add(x)]

def count_ocurrences_in_list(sequence):
    totals_by_word = []
    no_duplicates = remove_duplicates_in_list(sequence)
    for word in no_duplicates:
        totals_by_word.append((word,sequence.count(word)))
    return totals_by_word

def print_results(sequence):
    print('', end='\n')    
    for item in sequence:
        print('%s, %s' % (item[0], item[1]))    

def print_to_file(sequence, output):
    with open(output, mode='w', encoding='utf-8') as output_file:
        output_file.write('\n')
        for item in sequence:
            output_file.write('%s, %s\n' % (item[0], item[1]))

def main(argv=None):
    if argv is None:
        argv = sys.argv
    
    if len(argv) != 4:
        print("usage: program language sourcefile outputfile")
        sys.exit()

    programming_language = sys.argv[1]    
    source_file = sys.argv[2]    
    output_file = sys.argv[3]     
    
    language_keywords = get_language_keywords(programming_language)
    comment_character = get_line_comment_char(programming_language)
    
    total_keywords_found = 0
    list_of_keywords_found = []
    
    line_number = 0
    with open(source_file, encoding='utf-8') as source_code:
        for line in source_code:
            line_number += 1
            comment_idx = line.find(comment_character)
            if comment_idx >= 0:
                line = line[0:comment_idx]
            line = remove_special_characters(line)
            words = line.split()
            for word in words:
                if is_keyword(word, language_keywords):                    
                    list_of_keywords_found.append(word)
                    total_keywords_found = total_keywords_found + 1

    totals_to_output = []    
    totals_to_output.append((programming_language.capitalize(),str(total_keywords_found)))
    totals_to_output.extend(count_ocurrences_in_list(list_of_keywords_found))
    
    print_results(totals_to_output)
    print_to_file(totals_to_output, output_file)
    
if __name__ == "__main__":    
    main()

Friday, January 14, 2011

How many keywords in your source code? Round 2



Last year, in July 2011, I wrote a post about How many keywords do you type in your code?.

"Have you ever wondered how many keywords (reserved words) do you type in your programs? Can you type more or type less without changing what your program does? Can you change programming language and save some typing? And if so, to which language?". 

Back then, I tried to answer those questions by showing some comparative graphics with the number of keywords needed to build 2 versions (minimal and verbose) of the same little program in 20 different programming languages (C#, VB.NET, C++/CLI, F#, Boo, Phalanger, IronPython, IronRuby, Delphi Prism, Zonnon, Nemerle, Cobra, JScript.NET, Java, JavaFX, Groovy, Jython, JRuby, Fantom, Scala).


The program I chose was an OO version of the famous Hello World (Archive posts June-July 2010) and had the following structure:

// OO Hello World
    // Import,using,etc.
    // Class
        // Field
        // Constructor
        // Method
    // Program
        // Instantiate Class
        // Call Method = OUTPUT (Hello, World!)

Finally, I added some comments and thoughts about the results, but... What if we do the same with a bigger example? Will the results be more or less the same if I a more elaborated program is used to do the comparison? Do the most verbose language and the most minimalistic of the previous post will still hold the title?

That's exactly what this new post is all about! :) a new comparison on a more elaborated, still small, program using many more language constructs following the sample rules of the previous comparison:

  • 2 Versions Minimal and Verbose.
  • 21 Programming Languages (the previous 20 + Gosu).
  • Primitive Types such as int, float, double, string not considered as keywords.
  • Same OO program and structure (taken from series Language's Basics by Example).
  • OO Hello World was small enough to count by hand, but this time I created a little script written in Python 3 that does the automatic counting for me :) (source code to be provided in my next post). 

// Language Basics
    // Greet Class
        // Fields or Attributes
        // Properties
        // Constructor
        // Overloaded Constructor
        // Method 1
            // "if-then-else" statement
        // Method 2
            // "for" statement
        // Overloaded Method 2.1
            // "while" statement
        // Overloaded Method 2.2
            // use Date Class
            // "switch/case" statement

    // Console Program
        // Define object of type Greet 
        // Instantiate Greet. Call Constructor
        // Call Set Properties
        // Call Method 2
        // Call Method 2.1 and Get Properties
        // Call Method 2.2
        // Stop and exit - Read Input From Console

Here below th graphs! Click on the images to enlarge.

Total Keywords by Language

Language Keywords
IronPython 31
Jython 31
IronRuby 38
JRuby 38
Scala 40
Fantom 46
Java 50
Zonnon 50
Gosu 53
Groovy 57
Nemerle 59
Boo 66
JavaFX 70
JScript.NET 75
C++/CLI 84
Phalanger 92
F# 97
C# 102
Delphi Prism 134
VB.NET 137
Cobra 139



Version 1 (Minimal)

Language Keywords
VB.NET 130
Delphi Prism 94
Phalanger 89
Cobra 79
JScript.NET 72
Groovy 72
Gosu 72
C# 69
Boo 68
Zonnon 66
Java 65
JavaFX 64
C++/CLI 59
Jython 51
IronPython 48
JRuby 46
IronRuby 46
Fantom 46
F# 41
Scala 37
Nemerle 33


Version 2 (Verbose)

Language Keywords
VB.NET 169
Delphi Prism 134
JScript.NET 118
Gosu 114
Boo 114
Cobra 109
JavaFX 105
Phalanger 103
Java 103
C# 103
Groovy 101
C++/CLI 101
Zonnon 90
Fantom 80
Nemerle 67
F# 54
Jython 53
IronPython 50
JRuby 48
IronRuby 48
Scala 41



Both (Minimal and Verbose) 

Language Minimal Verbose
VB.NET 130 169
Delphi Prism 94 134
Phalanger 89 103
Cobra 79 109
JScript.NET 72 118
Groovy 72 101
Gosu 72 114
C# 69 103
Boo 68 114
Zonnon 66 90
Java 65 103
JavaFX 64 105
C++/CLI 59 101
Jython 51 53
IronPython 48 50
JRuby 46 48
IronRuby 46 48
Fantom 46 80
F# 41 54
Scala 37 41
Nemerle 33 67



Compare Basics and HelloWorld (Minimal and Verbose) 

Language| Basics Minimal| Basics Verbose| Basics Differ| Hello Minimal| Hello Verbose| Hello Differ|
VB.NET 13016939243410
Delphi Prism 941344035394
Phalanger 891031410166
Cobra 79109309145
JScript.NET 72118467158
Groovy 72101295116
Gosu 72114425138
C# 691033410155
Boo 681144671710
Zonnon 66902416215
Java 651033812164
JavaFX 641054151510
C++/CLI 591014211165
Jython 51532462
IronPython 48502462
JRuby 46482660
IronRuby 46482660
Fantom 468034594
F# 4154135127
Scala 374145105
Nemerle 3367349167


CONCLUSIONS

As with the previous post, we can still notice the 3 main groups of languages:
1. Scripting/Dynamic Languages (Python, Ruby, Groovy, etc.) fewer keywords
2. Functional Languages (F#, Scala, Nemerle, etc.) more or less than the previous group
3. Imperative/Static Languages (C#, C++, VB.NET, Java, etc.) more keywords

We can also see that the scripting/dynamic languages are the ones that define the fewer keywords and that's probably the reason why there are few or no difference in the number of keywords typed between the 2 versions of the same program (see latest graph above).

The difference between the number of keywords of the most verbose and the most minimalistic program is of:
Basics Minimal: VB.NET 130 vs Nemerle 33 (97 keys of difference)
Basics Verbose: VB.NET 169 vs Scala 41 (128 keys of difference)
Big differences... and they could be much bigger if we include primitive types as keywords (because they are keywords, but were excluded for this comparison)

When comparing a small program such as the OO Hello World in which didn't use many language constructs we still saw a big difference between the most verbose and the most minimalistic languages. That is still true when many more statements and constructs are added to the code as in the case of: Delphi Prism and VB.NET, however, this time we can clearly see that the most verbose language is not Delphi Prism but VB.NET!!!

So, VB.NET congratulations! You are the most extra-typing language among the .NET and Java languages. I guess that's why Visual Studio 2010 auto-completes all the closing blocks keywords :D so you don't need to type that many... I'm wondering what about those programmers that love to code in raw text using notepad(++?)... I guess those brave of hearth do not program using VB. Am I right?

Nevertheless, I'm very curious about running the keywords counting on a Real Life program (hundreds-thousands lines of code) and see what the result is.

And now, about the most minimalistic language? Well, this time was Nemerle, followed by Scala and F#. The 3 languages are multi-paradigm languages, but are mainly inspired by the Functional ones, so we can probably assume that functional languages use less keywords, less typing even if using their OO syntax features; that's probably why there are lots of blog posts about the difference in amount of code between Scala and Java; of course they always compare Java's Imperative syntax vs Scala's Functional syntax, which is fare enough because Scala is meant to be used as a functional language. Right? So, in summary, using OO or Functional syntax, you will usually have smaller programs. Of course, that depends how you write code and if you use, let's say, match-case instead of if-then-else.

So what happened to the Scripting languages? weren't they the ones with smaller keywords sets? and I'm not talking about Groovy because remember that Groovy needs to be Java syntax compatible, but Python and Ruby?

Let's have a look:

Ruby 48
module 1
class 1
def 11 # this is understandable
end 17 # and here is where the most keyword go! 
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1 # using the case construct also requires lots of keys because 
when 4 # it uses when and then for each case you want to validate against
then 4 #

IronPython 50
import 2
from 1
class 1
def 12  # this is understandable
return 5
if 2
else 2
for 1
in 1
print 4  # print is a keyword but other languages use  
           # Console.WriteLine | System.out.println 
while 1
or 16 # and here is where the most keyword go because 
           # python has no switch | case | match syntax 
elif 2


What else... oh yes. Verbosity of the language has nothing to do with its elegance or expressiveness (for instance Delphi Prism vs Scala|F#).

Finally, counting keywords in your code is probably not relevant, because it will vary a lot between programs, styles, paradigms, if code was automatically generated, manually typed, and so on.
In my case I used the 2 edges to compare the "Minimal" and "Verbose", but in real coding a combination based on the above might be used.

That's pretty much it.

Here below I added the counting results for all the 21 languages in case you wonder which keywords




Basics MinimalBasics Verbose
Boo 68Boo 114
import 1
class 1
as 17
get 3
return 5
set 3
def 6
constructor 2
self 4
private 1
if 2
else 2
for 1
in 1
while 1
or 16
elif 2
namespace 1
import 1
private 5
class 1
as 24
public 9
get 3
return 5
self 28
set 3
def 7
constructor 2
if 2
else 2
for 1
in 1
while 1
or 16
elif 2

Basics MinimalBasics Verbose
Cobra 79Cobra 109
class 2
var 3
pro 3
as 12
get 3
return 5
set 3
cue 2
base 2
def 5
is 1
private 1
if 1
else 2
for 1
in 1
print 4
while 1
branch 1
on 4
or 20
any 1
to 1
use 1
namespace 1
class 2
is 12
public 10
var 3
as 18
pro 3
get 3
return 5
set 3
cue 2
base 2
def 5
private 1
if 1
else 2
for 1
in 1
print 4
while 1
branch 1
on 4
or 20
shared 1
any 1
to 1

Basics MinimalBasics Verbose
C++/CLI 59C++/CLI 101
using 1
namespace 1
class 1
public 2
property 3
return 5
void 6
this 3
private 1
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
gcnew 1
using 1
namespace 2
private 5
class 1
public 14
property 3
return 6
this 27
void 6
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
gcnew 1

Basics MinimalBasics Verbose
C# 69C# 103
using 1
class 2
public 8
get 3
return 5
set 3
value 3
this 3
if 1
else 1
void 4
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 1
using 1
namespace 1
internal 2
class 2
private 4
public 9
get 3
return 5
this 29
set 3
value 3
if 1
else 1
void 4
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 1

Basics MinimalBasics Verbose
DelphiPrism 94DelphiPrism 134
namespace 1
interface 1
uses 1
type 2
class 4
private 1
method 14
public 2
property 3
read 3
write 3
constructor 4
end 17
array 2
of 3
implementation 1
begin 13
if 1
then 1
result 2
else 2
for 1
to 2
step 1
do 2
var 3
while 1
case 1
new 1
exit 1
namespace 1
interface 1
uses 1
type 2
public 11
class 4
private 6
var 6
method 14
property 3
read 3
write 3
constructor 4
end 17
array 2
of 3
implementation 1
begin 13
self 23
if 1
then 1
result 2
else 2
for 1
to 2
step 1
do 2
while 1
case 1
new 1
exit 1

Basics MinimalBasics Verbose
Fantom 46Fantom 80
class 2
private 4
return 5
it 3
new 1
if 1
else 1
for 1
while 1
switch 1
case 24
default 1
static 1
internal 1
class 2
private 4
public 9
return 5
this 24
it 3
new 1
if 1
else 1
for 1
while 1
switch 1
case 24
default 1
static 1

Basics MinimalBasics Verbose
F# 42F# 54
open 1
type 1
let 9
mutable 4
member 7
with 4
and 3
new 2
private 1
if 1
then 1
else 1
for 1
to 2
do 2
while 1
match 1
namespace 1
open 1
type 1
public 8
class 1
let 9
mutable 4
member 7
with 4
and 3
new 2
private 1
if 1
then 1
else 1
for 1
to 2
do 2
while 1
match 1
end 1
module 1

Basics MinimalBasics Verbose
Gosu 72Gosu 114
uses 4
class 1
var 8
property 6
get 4
return 5
set 3
private 1
function 4
else 1
for 1
while 1
new 3
switch 1
case 24
break 4
default 1
uses 4
public 12
class 1
private 4
var 8
property 6
get 4
return 5
this 27
set 3
function 4
else 1
for 1
while 1
new 3
switch 1
case 24
break 4
default 1

Basics MinimalBasics Verbose
Groovy 72Groovy 101
class 1
private 4
def 20
return 5
this 3
if 1
else 1
for 1
in 2
while 1
new 3
switch 1
case 24
break 4
default 1
package 1
public 12
class 1
private 4
return 5
this 29
void 6
def 3
if 1
else 1
for 1
in 2
while 1
new 3
switch 1
case 24
break 5
default 1

Basics MinimalBasics Verbose
IronPython 48IronPython 50
from 1
import 1
class 1
def 11
return 5
if 2
else 2
for 1
in 1
print 4
while 1
or 16
elif 2
import 2
from 1
class 1
def 12
return 5
if 2
else 2
for 1
in 1
print 4
while 1
or 16
elif 2

Basics MinimalBasics Verbose
IronRuby 46IronRuby 48
class 1
def 11
end 16
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4
module 1
class 1
def 11
end 17
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4

Basics MinimalBasics Verbose
Java 65Java 103
package 2
import 2
class 2
private 4
return 5
void 7
this 3
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
public 2
static 1
new 2
package 2
import 2
public 14
class 2
private 4
return 5
this 29
void 7
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 2

Basics MinimalBasics Verbose
JavaFX 64JavaFX 105
import 4
class 1
var 6
function 11
return 5
init 1
if 5
else 5
for 1
in 2
while 1
def 1
new 1
or 20
package 1
import 4
public 11
class 1
var 6
function 11
return 5
this 29
init 1
if 5
else 5
for 1
in 2
while 1
def 1
new 1
or 20

Basics MinimalBasics Verbose
JRuby 46JRuby 48
class 1
def 11
end 16
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4
module 1
class 1
def 11
end 17
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4

Basics MinimalBasics Verbose
JScript.NET 72JScript.NET 118
import 1
class 1
var 7
function 12
get 3
return 5
set 3
this 3
private 1
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
new 1
import 1
package 1
public 12
class 1
private 4
var 7
function 13
get 3
return 5
this 29
set 3
if 1
else 1
void 3
for 1
while 1
switch 1
case 24
break 5
default 1
new 1

Basics MinimalBasics Verbose
Jython 51Jython 53
from 2
import 2
class 1
def 11
return 5
if 2
else 2
for 1
in 2
print 4
while 1
or 16
elif 2
import 3
from 2
class 1
def 12
return 5
if 2
else 2
for 1
in 2
print 4
while 1
or 16
elif 2

Basics MinimalBasics Verbose
Nemerle 33Nemerle 67
using 1
class 1
mutable 5
public 8
this 5
private 1
if 1
else 1
void 3
for 1
while 1
def 2
match 1
_ 2
using 1
namespace 1
internal 1
class 1
private 4
mutable 6
public 10
this 29
if 1
else 1
void 4
for 1
while 1
def 1
match 1
_ 2
module 1
static 1

Basics MinimalBasics Verbose
Phalanger 89Phalanger 103
namespace 1
class 2
private 4
function 12
return 5
this 24
if 1
else 1
for 1
echo 4
while 1
switch 1
case 24
break 4
default 1
static 1
new 1
exit 1
namespace 2
class 2
private 4
public 11
function 12
return 6
this 24
if 1
else 1
for 1
echo 4
while 1
switch 1
case 24
break 5
default 1
static 1
new 1
exit 1

Basics MinimalBasics Verbose
Scala 37Scala 41
import 1
class 1
private 4
var 4
def 12
this 2
if 1
else 1
for 1
while 1
val 2
match 1
case 5
new 1
package 1
import 2
class 1
private 4
var 4
def 13
this 2
if 1
else 1
for 1
while 1
val 2
match 1
case 5
object 1
new 1

Basics MinimalBasics Verbose
VB.NET 130VB.NET 169
Imports 1
Friend 2
Class 2
Private 4
As 22
Property 6
Get 6
Return 5
End 21
Set 6
ByVal 11
Sub 12
New 3
Function 2
If 2
Then 1
Else 2
For 1
To 5
Next 1
Dim 3
While 2
Select 2
Case 6
Module 2
Imports 1
Namespace 2
Friend 2
Class 2
Private 4
As 22
Public 9
Property 6
Get 6
Return 5
Me 27
End 22
Set 6
ByVal 11
Sub 12
New 3
Function 2
If 2
Then 1
Else 2
For 1
To 5
Next 1
Dim 3
While 2
Select 2
Case 6
Module 2

Basics MinimalBasics Verbose
Zonnon 66Zonnon 90
module 1
import 1
type 1
object 1
var 5
procedure 10
begin 12
return 5
end 16
if 1
then 1
else 2
for 1
to 2
do 2
while 1
case 1
of 1
new 1
exit 1
module 1
import 1
type 1
object 1
var 5
procedure 10
begin 12
return 5
self 24
end 16
if 1
then 1
else 2
for 1
to 2
do 2
while 1
case 1
of 1
new 1
exit 1