Tuesday, 28 August 2012

Android App Development Tutorial


This tutorial is meant to target devlopers who have little or no experience in Android or C# development. If you are brand new in programming you will probably be able to follow but you will gain a lot from reading up on basic programming concepts such as classes, objects, class inheritance and events. If you are experienced you will know what parts to skip :-)

To get started with programming for the Android platform we are going to make a very simple application. Though, it will be a bit more advanced than the barebone "Hello World"-app or the simple starter app that is being generated automatically by the development framework when creating a new Android project.


Our Basic application


The app we are gong to build is a reaction tester. A program that will count how many millisconds it takes you to press a button after you have been given the "go" signal. In this first tutorial we will keep it very simple and then we will add more feaures in the upcoming tutorials in our Android App Development-series.

The program will be doing the following: When it loads it will alert the user to be ready to react. Seconds later a "Go!" message will be given signalling the user to react. The user reacts by pressing a button on the screen. The instant the button is pressed the program will calculate the time from the signal was given until the button was pressed. The resulting time will be displayed on the screen (and the user will be able to start the process again to see if he can beat his previous time).


Setting up namespaces


Our program starts out like this:


using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace ReactionTimer
{


First we are applying the using directive to be able to reference different elements of the Mono (for Android) Framework that we will be needing for our program. For instance we are going to use a Button which is a specific graphical element with a specific set of features and which is drawn on the screen in a specific way by the Android device. A Button is located in the Android.Widget namespace. A namespace is simply a way of dividing code into logical units giving it a proper a structure that allows programmers to find what they need (easily, hopefully). Without our using directive we would need to write Android.Widget.Button in order to reference the needed class in the Mono Framework. Now, we can instead just write Button in our code. When the program is prepared for execution (compiled) the compiler will know what type of button we are referring to and where to find it.

In the same way we are also referring the System namespace (in the very first line) which is not a reference to Android specific code elements but to general code from the .NET Framework (now in its Mono implementation as we are using the Mono Framework).

After that on line 10 we are creating our very own name space (yay, our first piece of original code) ReactionTimer. As we only have one main file and one namespace we do not have any special benefits from this. However, as our application grows, making use of cleverly named spaces can be quite useful.


The Android Activity class



Next we come to our first class Activity1 which inherits from the Activity class in the Android.App namespace

See the piece of code below:


[Activity(Label = "Reaction Tester", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{


An activity on Android is logical construct (besides being a class) that refers to something the user can do. For at user to do something a user interface (UI)is required. Thus, a primary function of an Activity is to control a window on which graphical items (UI-elements) are placed for the the user to interact with.

In our application our activity is to carry our a reaction as fast as possible. This requires only a single screen and so we only have one Activity class. If we needed multiple screens we would create multiple classes. Instaead of Activity1 we could have named our activity differently - for exaple "ReactionScreen".

Just above our Activity class we see what is called an attribute. An attribute is not part of the code itself and is not influencing the program when it is running. Rather it is a form of annotation that can be used by the programming environment when the code is being processed and made into an executable form.

In our case we have an ActivityAttribute and it has some parameters called Label, MainLauncher and Icon. These attributes are being used by the Mono framework and what happens specifically is that during the build process the Mono framework looks for all the class attributes and uses the data found in order to generate an XML file. This resulting file is called "AndroidManifest.xml" and is a file that needs to be included within every Android application. It is a kind of settings file that tells Android something about the program and how to deal with it. In our case our device will know that the label to use for our activity is "Reaction Tester" (will be shown on the screen when the app is running), that our activity class is to be launched when the program starts, and it knows where to find the icon to associate with our program.


Content of the Activity class



Our Activity class contains the following code:


private ChangeStateTimer timer;
private State state;
private long startTime;
private Button button;
private TextView label;

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);

    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);

    // Get our button from the layout resource and attach an event to it
    this.button = FindViewById<Button>(Resource.Id.buttonMain);
    this.button.Click += new EventHandler(HandleUserReaction);
    //Ensure the button cannot be pressed until we need it to
    this.button.Enabled = false;
    //Get a reference to the label from the layout resource
    this.label = FindViewById<TextView>(Resource.Id.labelResult);

    this.state = State.Stopped;
    this.timer = new ChangeStateTimer(10000, 2000, this);
    this.timer.Start();
}


First we have five variables (called Fields in C#). The two first are used to hold references to a timer that we will need and to the state we discussed before. The third of them will hold the time (measure in milliseconds) for when the "go"-signal was given so that we can use it later to see how much time passed until the user pressed the button. Finally, the two last fields will be referring to our two UI-items which is a Button and a TextView (which we will be referring to as a "label").

Next we have a method that is being called automatically by the system once the program has started and our Activity has been created. This is the way that Android informs us that "Ok, now your program has started and I am going to turn it over to you now. So, get ready.". In this method we have to prepare a few things so that our program can later function as we intend.

Well, first we have to do something for Android which is to call the OnCreate method on the base class. This is so that the Activity class can do it's magic (setting up something that needs to be set-up for an Android program to run - which we do not need to concern ourselves with).

The first major thing we do is to load our user interface by calling the SetContentView method of our activity passing it our layout as a parameter. Our layout is stored in an XML template file called "Main" and located amongst our program Resources in the "Layout" folder (see file content later). It needs to be connected to our activity so that it will display the UI-elements we have marked up there.

Then we locate our button and label in our template and save a reference to them so that we can do something with them later. Also, we attach an event handler to the Click event of the button. This is done by passing the name of our method - which is HandleUserReaction to a so-called delegate.

A delegate is specific concept in C# that acts as a form of a contract. The purpose is to constrict exactly what form a method should have in order to be called by a particular event. The event in this case is the Click event of a button. From documentation we know that it is the EventHandler delegate that holds the contract related this event. So, as long as our method conforms to the contract laid out by this particular delegate we can be sure that it can be executed when the Click event of the button has been triggered.

Now we set the state of our application (see more below). At this point we want to remember that we are not currently Running (but rather Stopped) meaning that we have not yet started the experiment of seeing how fast the user can press the button after we tell him to.

Lastly, we create a new instance of our timer. We give it a few parameters with the most interesting being the first one which is used to set how many milliseconds the countdown should last. A deeper description will follow a few paragraphs down.


Creating state for our application


Next we make use of the enumeration data type (created with the enum keyword) containing two items. These are states which we will logically have to handle in our application and with our enum we are able to asily assign and retrieve them.

What the states are and their purpose should be evident from the code and the comments:


private enum State {
    Running,//The test is running and we await the reaction from the user
    Stopped//The test is not running (which will be the case at start-up or after the user has reacted)
}


The timer class


Explanation of the timer class to follow


      private class ChangeStateTimer : CountDownTimer
        {
            Activity1 activity;

            public ChangeStateTimer(long finalTime, long intervals, Activity1 activity)
                : base(finalTime, intervals)
            {
                this.activity = activity;
            }

            public override void OnFinish()
            {
                this.activity.GiveStartSignal();
            }

            public override void OnTick(long millisUntilFinished)
            {
                //Not using this method as we are not using the intervals 
            }
        }
    }
}

Ready, set, Go!


Next we have the GiveStartSignal method that will be called by the timer once it has finished counting down. At this point we are ready to time the reaction of the user.

private void GiveStartSignal()
{
    this.label.Text = "Waiting for your reaction.";
    this.button.Text = "Now!";
    this.button.Enabled = true;
    this.state = State.Running;
    this.startTime = SystemClock.CurrentThreadTimeMillis();
}


To alert the user that we are awaiting his reaction we change the text of our label to "Waiting for your reaction.". Also, we change the text of our button to "Now!". More importantly we change the Enabled state of the button to true so that it will actually function.

We then set the state to Running and register the current time. Note, that it is not the actual time of day that we are recording but the time that has passed since our application has been started (measured in milliseconds). This is totally fine because we are not concerned about the actual time but only interested in being able calculate the difference between "now" and the point at which the user will have pressed the button.

You might have noticed that it says CurrentThreadTimeMillis. So, technically we are not necessarily getting the time elapsed since the start of the application itself but rather that of the thread that is handling our application. A thread is a mechanism through which the processer is able to prioritize the execution of different programs (and different parts of a single program in case of multi-threaded programs).

So, now the "click is ticking" and the program is waiting for the user to press the "reaction"-button - which brings us to the last part of our code.

Handling states


Finally, we come to the method we assigned to the Click event of our button. Looking throug the code you will see that is uses our State enum to check what part of the code in the method to execute:

private void HandleUserReaction(Object sender, EventArgs e)
{
    if (this.state == State.Running)
    {
        //We have been waiting for a reaction and now we need to see how long it took
        long reactionTime = SystemClock.CurrentThreadTimeMillis() - this.startTime;
        this.label.Text = "You reacted in: " + reactionTime.ToString() + " milliseconds.";
        this.button.Text = "Restart";
        this.state = State.Stopped;
    }
    else if (this.state == State.Stopped)
    {
        //State is stopped and so a new click means we have to start over 
        this.label.Text = "Stand by for the button to signal a start";
        this.button.Text = "Stand by ...";
        this.button.Enabled = false;//Button must not be clickable now because we await for system to give the signal to the user
        this.timer.Start();
    }
}

First we check if we are in the Running state. If this is the case the user has just reacted and pressed the button as fast as humanly possible.

Therefore, we look at the current point in time again - and subtract the value we stored previously when the "go"-signal was given. Then we graciously present the user with the fact that it takes him just about half a second to press a button.

Lastly, we change the text of the button to "Restart" so the user can see that the way to beat himself trying to squeeze the reaction down to a quarter of a second is to once again press the same darn button. For that to work we also change the state to Stopped so that our program will execute the other part of the method next time it is called.

when the other part, and the last part of our program, is run, we know that the user has pressed the button again and we know that the state is Stopped. Consequently, what we must do is to start the timer once again so it can make a new countdown towards a new "go"-signal.

Also, we disable the button so that our user can see that the button is not currently to be pressed (if it was the timer would simply be restarted). As you test the program you might see that the user can cheat by hammering the button repeatedly hoping to trigger it the very instant it is re-enabled when the new signal is given. This problem we will tackle in the next tutorial where we will generally look at how we can enhance the current version.

The XML User Interface


Our graphical elements are contained in an XML file that acts as a template for our program. The UI-items can also be added to a screen directly through code but since the programming framework automactially generates a layout file as part of the model application we will stick to this way of going about it. Also, it is generaly good programming practice to separate programming logic from UI-layout.

<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       >
   <Button  
       android:id="@+id/buttonMain"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text=""
       />
    
       <TextView
           android:id="@+id/labelResult"
           android:text=""
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
       />
   </LinearLayout>

In the file we see that we have our Button and Textview and that they are contained in a LinearLayout. The tags all refer to classes in the Android Framework and LinearLyout is a class responsible for grouping controls and laying them out on the screen in a particular (liniear) way ("linear" means that the controls will be positioned one after another).

Besides the orientation of the layout which is set to "vertical" we see that special attributes are used for assigning height and width. The value "fill_parent" means that the control will take up as much space as it can limited only by its containing parent - while "wrap_content" means that the control will extend as much as possible to contain the content it holds (in our case the button and label will be as high as needed in order to contain the text we need them to show).

Now we have a working Android application. Good luck, keep studying and practising. 
As always, comments and questions are welcome, we'll try our best to answer them when we can. 

Helpful and productive suggestions and corrections, if any are needed are very much appreciated through our contact page.


Pascal Programming Lesson #14 - Linked Lists


A linked list is like an array except that the amount of elements in a linked list can change unlike an array. A linked list uses pointers to point to the next or previous element.

Single linked lists

There are 2 types of single linked lists which are called queues and stacks.

Queues

A queue is like standing in a queue at a shop. The first person that joins a queue is the first person to be served. You must always join at the back of a queue because if you join at the front the other people will be angry. This is called FIFO(First In First Out).

Item 1 --> Item 2 --> Item 3 --> (Until the last item)

Each item of a linked list is a record which has the data and a pointer to the next or previous item. Here is an example of how to declare the record for a queue and a pointer to a queue record as well as the variables needed:

program queue;

type
   pQueue = ^tqueue;
   tQueue = record
      data: integer;
      next: pQueue;
   end;

var
   head, last, cur: pQueue;

begin
end.

We will now make 3 procedures. The first procedure will add items to the list, the second will view the list and the third will free the memory used by the queue. Before we make the procedures lets first take a look at the main program.

begin
   head := nil; {Set head to nil because there are no items in the queue}
   add(1) {Add 1 to the queue using the add procedure};
   add(2);
   add(3);
   view; {View all items in the queue}
   destroy; {Free the memory used by the queue}
end.

The add procedure will take an integer as a parameter and add that integer to the end of the queue.

procedure add(i: integer);
begin
   new(cur); {Create new queue item}
   cur^.data := i; {Set the value of the queue item to i}
   cur^.next := nil; {Set the next item in the queue to nil because it doesn't exist}
   if head = nil then {If there is no head of the queue then}
      head := cur {Current is the new head because it is the first item being added to the list}
   else
      last^.next := cur; {Set the previous last item to current because it is the new last item in the queue}
   last := cur; {Make the current item the last item in the queue}
end;

The view procedure uses a loop to display the data from the first item to the last item of the queue.

procedure view;
begin
   cur := head; {Set current to the beginning of the queue}
   while cur <> nil do {While there is a current item}
      begin
         writeln(cur^.data); {Display current item}
         cur := cur^.next; {Set current to the next item in the queue}
      end;
end;

The destroy procedure will free the memory that was used by the queue.

procedure destroy;
begin
   cur := head; {Set current to the beginning of the queue}
   while cur <> nil do {While there is a item in the queue}
      begin
         cur := cur^.next; {Store the next item in current}
         dispose(head); {Free memory used by head}
         head := cur; {Set the new head of the queue to the current item}
      end;
end;

Stacks

To understand a stack you must think about a stack of plates. You can add a plate to the top of the stack and take one off the top but you can't add or take away a plate from the bottom without all the plates falling. This is called LIFO(Last In First Out).

Item 1 <-- Item 2 <-- Item 3 <-- (Until the last item)

When you declare the record for a stack item you must use previous instead of next. Here is an example.

program stack;

type
   pStack = ^tStack;
   tStack = record
      data: integer;
      prev: pStack;
   end;

var
   last, cur: pStack;

begin
   last := nil;
   add(3);
   add(2);
   add(1);
   view;
   destroy;
end.

You will see that the numbers are added from 3 to 1 with a stack instead of 1 to 3. This is because things must come off the top of the stack instead of from the head of a queue.

The add procedure adds the item after the last item on the stack.

procedure add(i: integer);
begin
   new(cur); {Create new stack item}
   cur^.data := i; {Set item value to the parameter value}
   cur^.prev := last; {Set the previous item to the last item in the stack}
   last := cur; {Make the current item the new last item}
end;

The view and destroy procedures are almost the same as with a queue so they will not need to be explained.

procedure view;
begin
   cur := last;
   while cur <> nil do
      begin
         writeln(cur^.data);
         cur := cur^.prev;
      end;
end;

procedure destroy;
begin
   while last <> nil do
      begin
         cur := last^.prev;
         dispose(last);
         last := cur;
      end;
end;

Pascal Programming Lesson #13 - Pointers


A pointer is a type of variable that stores a memory address. Because it stores a memory address it is said to be pointing to it. There are 2 types of pointers which are typed and untyped. A typed pointer points to a variable such as an integer. An untyped pointer can point to any type of variable.

Declaring and using typed pointers

When you declare a typed pointer you must put a ^ in front of the variable type which you want it to point to. Here is an example of how to declare a pointer to an integer:

program Pointers;

var
   p: ^integer;

begin
end.

The @ sign can be used in front of a variable to get its memory address. This memory address can then be stored in a pointer because pointers store memory addresses. Here is an example of how to store the memory address of an integer in a pointer to an integer:

program Pointers;

var
   i: integer;
   p: ^integer;

begin
   p := @i;
end.

If you want to change the value stored at the memory address pointed at by a pointer you must first dereference the pointer variable using a ^ after the pointer name. Here is an example of how to change the value of an integer from 1 to 2 using a pointer:

program Pointers;

var
   i: integer;
   p: ^integer;

begin
   i := 1;
   p := @i;
   p^ := 2;
   writeln(i);
end.

You can allocate new memory to a typed pointer by using the new command. The new command has one parameter which is a pointer. The new command gets the memory that is the size of the variable type of the pointer and then sets the pointer to point to the memory address of it. When you are finished using the pointer you must use the dispose command to free the memory that was allocated to the pointer. Here is an example:

program Pointers;

var
   p: ^integer;

begin
   new(p);
   p^ := 3;
   writeln(p^);
   dispose(p);
end.

Declaring and using untyped pointers

When you declare an untyped pointer you must use the variable type called pointer.

program Pointers;

var
   p: pointer;

begin
end.

When you allocate memory to an untyped pointer you must use the getmem command instead of the newcommand and you must use freemem instead of disposegetmem and freemem each have a second parameter which is the size in bytes of the amount of memory which must be allocated to the pointer. You can either use a number for the size or you can use the sizeof function to get the size of a specific variable type.

program Pointers;

var
   p: pointer;

begin
   getmem(p,sizeof(integer));
   freemem(p,sizeof(integer));
end.

Pascal Programming Lesson #12 - Units

We already know that units, such as the crt unit, let you use more procedures and functions than the built-in ones. You can make your own units which have procedures and functions that you have made in them.


To make a unit you need to create new Pascal file which we will call MyUnit.pas. The first line of the file should start with the unit keyword followed by the unit's name. The unit's name and the unit's file name must be exactly the same.

unit MyUnit;

The next line is the interface keyword. After this you must put the names of the procedures that will be made available to the program that will use your unit. For this example we will be making a function calledNewReadln which is like Readln but it lets you limit the amount of characters that can be entered.

unit MyUnit;

interface

function NewReadln(Max: Integer): String;

The next line is implementation. This is where you will type the full code for the procedures and functions. We will also need to use the crt unit to make NewReadln. We end the unit just like a normal program with the endkeyword.

unit MyUnit;

interface

function NewReadln(Max: Integer): String;

implementation

function NewReadln(Max: Integer): String;
var
   s: String;
   c: Char;
begin
   s := '';
   repeat
      c := ReadKey;
      if (c = #8){#8 = BACKSPACE} and (s <> '') then
         begin
            Write(#8+' '+#8);
            delete(s,length(s),1);
         end;
      if (c <> #8) and (c <> #13){#13 = ENTER} and (length(s) < Max) then
         begin
            Write(c);
            s := s + c;
         end;
   until c = #13;
   NewReadln := s;
end;

end.

Once you have saved the unit you must compile it. Now we must make the program that uses the unit that we have just made. This time we will type MyUnit in the uses section and then use the NewReadln function.

program MyProgram;
 
uses
   MyUnit;
 
var
   s: String;
 
begin
   s := NewReadln(10);
end.

Pascal Programming Lesson #11 - Data Files


Data files are different from text files in a few ways. Data files are random access which means you don't have to read through them line after line but instead access any part of the file at any time. Here is how you declare a data file:

program DataFiles;

var
   f: file of Byte;

begin
end.


We then use Assign in the same way as we do with a text file.

program DataFiles;

var
   f: file of Byte;

begin
   Assign(f,'MyFile.dat');
end.


You can use Rewrite to create a new file or overwrite an existing one. The difference between text files and data files when using Rewrite is that data files can be read and written to.

program DataFiles;

var
   f: file of Byte;

begin
   Assign(f,'MyFile.dat');
   Rewrite(f);
end.


Reset is the same as Rewrite except that it doesn't overwrite the file.

program DataFiles;

var
   f: file of Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
end.


When you write to a file using the Write command you must first put the value to be written to the file into a variable. Before you can write to or read from a data file you must use the Seek command to find the right place to start writing. You must also remember that data files start from position 0 and not 1.

program DataFiles;

var
   f: file of Byte;
   b: Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
   b := 1;
   Seek(f,0);
   Write(f,b);
end.


The Read command is used to read from a data file.

program DataFiles;

var
   f: file of Byte;
   b: Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
   Seek(f,0);
   Read(f,b);
end.


You must close a data file when you are finished with it just like with text files.

program DataFiles;

var
   f: file of Byte;
   b: Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
   Seek(f,0);
   Read(f,b);
   Close(f);
end.


The FileSize command can be used with the FilePos command to find out when you have reached the end of the file. FileSize returns the actual number of records which means it starts at 1 and not 0. The FilePoscommand will tell at what position in the file you are.

program DataFiles;

var
   f: file of Byte;
   b: Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
   while FilePos(f) <> FileSize(f) do
      begin
         Read(f,b);
         Writeln(b);
      end;
   Close(f);
end.


The Truncate command will delete everything in the file from the current position.

program DataFiles;

var
   f: file of Byte;

begin
   Assign(f,'MyFile.dat');
   Reset(f);
   Seek(f,3);
   Truncate(f);
   Close(f);
end.


One of the most useful things about data files is that you can use them to store records.

program DataFiles;

type
   StudentRecord = Record
      Number: Integer;
      Name: String;
   end;

var
   Student: StudentRecord;
   f: file of StudentRecord;

begin
   Assign(f,'MyFile.dat');
   Rewrite(f);
   Student.Number := 12345;
   Student.Name := 'John Smith';
   Write(f,Student);
   Close(f);
end.


Pascal Programming Lesson #10 - Text Files

You should by now know that a text file is a file with lines of text. When you want to access a file in Pascal you have to first create a file variable.


program Files;

var
   f: Text;

begin
end.

After the variable has been declared you must assign the file name to it.

program Files;

var
   f: Text;

begin
   Assign(f,'MyFile.txt');
end.

To create a new empty file we use the Rewrite command. This will overwrite any files that exist with the same name.

program Files;

var
   f: Text;

begin
   Assign(f,'MyFile.txt');
   Rewrite(f);
end.

The Write and Writeln commands work on files in the same way they work on the screen except that you must use an extra parameter to tell it to write to the file.

program Files;

var
   f: Text;

begin
   Assign(f,'MyFile.txt');
   Rewrite(f);
   Writeln(f,'A line of text');
end.

If you want to read from a file that already exists then you must use Reset instead of Rewrite. Use Readln to read lines of text from the file. You will also need a while loop that repeats until it comes to the end of the file.

program Files;

var
   f: Text;
   s: String;

begin
   Assign(f,'MyFile.txt');
   Reset(f);
   while not eof(f) do
      Readln(f,s);
end.

Append opens a file and lets you add more text at the end of the file.

program Files;

var
   f: Text;
   s: String;

begin
   Assign(f,'MyFile.txt');
   Append(f);
   Writeln(f,'Some more text');
end.

No matter which one of the 3 access types you choose, you must still close a file when you are finished using it. If you don't close it then some of the text that was written to it might be lost.



program Files;

var
   f: Text;
   s: String;

begin
   Assign(f,'MyFile.txt');
   Append(f);
   Writeln(f,'Some more text');
   Close(f);
end.

You can change a file's name with the Rename command and you can delete a file with the Erase command.

program Files;

var
   f: Text;

begin
   Assign(f,'MyFile.txt');
   Rename(f,'YourFile.txt');
   Erase(f);
   Close(f);
end.

To find out if a file exists, you must first turn off error checking using the {$I-} compiler directive. After that you must Reset the file and if IOResult = 2 then the file was not found. If IOResult = 0 then the file was found but if it is any other value then the program must be ended with the Halt command. IOResult loses its value once it has been used so we also have to put that into another variable before using it. You must also use {$I+} to turn error checking back on.

program Files;

var
   f: Text;
   IOR: Integer;

begin
   Assign(f,'MyFile.txt');
{$I-}
   Reset(f);
{$I+}
   IOR := IOResult;
   if IOR = 2 then
      Writeln('File not found');
   else
      if IOR <> 0 then
         Halt;
   Close(f);
end.

Pascal Programming Lesson #9 - Procedures and Functions


Procedures

Procedures are sub-programs that can be called from the main part of the program. Procedures are declared outside of the main program body using the procedure keyword. Procedures must also be given a unique name. Procedures have their own begin and end. Here is an example of how to make a procedure called Hello that prints "Hello" on the screen.

program Procedures;

procedure Hello;
begin
   Writeln('Hello');
end;

begin
end.

To use a procedure we must call it by using its name in the main body.

program Procedures;

procedure Hello;
begin
   Writeln('Hello');
end;

begin
   Hello;
end.

Procedures must always be above where they are called from. Here is an example of a procedure that calls another procedure.

program Procedures;

procedure Hello;
begin
   Writeln('Hello');
end;

procedure HelloCall;
begin
   Hello;
end;

begin
   HelloCall;
end.

Procedures can have parameters just like the other commands we have been using. Each parameter is given a name and type and is then used just like any other variable. If you want to use more than one parameter then they must be separated with semi-colons.

program Procedures;

procedure Print(s: String; i: Integer);
begin
   Writeln(s);
   Writeln(i);
end;

begin
   Print('Hello',3);
end.


Global and Local variables

The variables we have been using so far have been global because they can be used at any time during the program. Local variables can only be used inside procedures but the memory they use is released when the procedure is not being used. Local variables are declared just underneath the procedure name declaration.

program Procedures;

procedure Print(s: String);
var
   i: Integer;
begin
   for i := 1 to 3 do
      Writeln(s);
end;

begin
   Print('Hello');
end.


Functions

Functions are like procedures except they return a value. The function keyword is used instead of procedurewhen declaring a function. To say what data type the return value must be you must use a colon and the name of the type after the function's name.

program Functions;

function Add(i, j:Integer): Integer;
begin
end;

begin
end.

Assigning the value of a function to a variable make the variable equal to the return value. If you use a function in something like Writeln it will print the return value. To set the return value just make the name of the function equal to the value you want to return.

program Functions;

var
   Answer: Integer;

function Add(i, j:Integer): Integer;
begin
   Add := i + j;
end;

begin
   Answer := Add(1,2);
   Writeln(Add(1,2));
end.

You can exit a procedure or function at any time by using the Exit command.

program Procedures;

procedure GetName;
var
   Name: String;
begin
   Writeln('What is your name?');
   Readln(Name);
   if Name = '' then
      Exit;
   Writeln('Your name is ',Name);
end;

begin
   GetName;
end.

Pascal Programming Lesson #8 - Types, Records and Sets


Types

It is possible to create your own variable types using the type statement. The first type you can make is records. Records are 2 or more variables of different types in one. An example of how this could be used is for a student who has a student number and a name. Here is how you create a type:

program Types;

Type
   Student = Record
      Number: Integer;
      Name: String;
   end;

begin
end.

After you have created the type you must declare a variable of that type to be able to use it.

program Types;

Type
   StudentRecord = Record
      Number: Integer;
      Name: String;
   end;

var
   Student: StudentRecord;

begin
end.

To access the Number and Name parts of the record you must do the following:

program Types;

Type
   StudentRecord = Record
      Number: Integer;
      Name: String;
   end;

var
   Student: StudentRecord;

begin
   Student.Number := 12345;
   Student.Name := 'John Smith';
end.

The other type is a set. Sets are not very useful and anything you can do with a set can be done just as easily in another way. The following is an example of a set called Animal which has dog, cat and rabbit as the data it can store:

program Types;

Type
   Animal = set of (dog, cat, rabbit);

var
   MyPet: Animal;

begin
   MyPet := dog;
end.
You can't use Readln or Writeln on sets so the above way of using it is not very useful. You can create a range of values as a set such as 'a' to 'z'. This type of set can be used to test if a value is in that range.

program Types;

uses
   crt;

Type
   Alpha = 'a'..'z';

var
   Letter: set of Alpha;
   c: Char;

begin
   c := ReadKey;
   if c in [Letter] then
      Writeln('You entered a letter');
end.

Pascal Programming Lesson #7 - Arrays


Arrays are variables that are made up of many variables of the same data type but have only one name. Here is a visual representation of an array with 5 elements:

1value 1
2value 2
3value 3
4value 4
5value 5

Arrays are declared in almost the same way as normal variables are declared except that you have to say how many elements you want in the array.

program Arrays;

var
   a: array[1..5] of Integer;

begin
end.


We access each of the elements using the number of the elements behind it in square brackets.

program Arrays;

var
   a: array[1..5] of Integer;

begin
   a[1] := 12;
   a[2] := 23;
   a[3] := 34;
   a[4] := 45;
   a[5] := 56;
end.


It is a lot easier when you use a loop to access the values in an array. Here is an example of reading in 5 values into an array:

program Arrays;

var
   a: array[1..5] of Integer;
   i: Integer;

begin
   for i := 1 to 5 do
      Readln(a[i]);
end.

Sorting arrays

You will sometimes want to sort the values in an array in a certain order. To do this you can use a bubble sort. A bubble sort is only one of many ways to sort an array. With a bubble sort the biggest numbers are moved to the end of the array.
You will need 2 loops. One to go through each number and another to point to the other number that is being compared. If the number is greater then it is swapped with the other one. You will need to use a temporary variable to store values while you are swapping them.

program Arrays;

var
   a: array[1..5] of Integer;
   i, j, tmp: Integer;

begin
   a[1] := 23;
   a[2] := 45;
   a[3] := 12;
   a[4] := 56;
   a[5] := 34;

   for i := 1 to 4 do
      for j := i + 1 to 5 do
         if a[i] > a[j] then
         begin
            tmp := a[i];
            a[i] := a[j];
            a[j] := tmp;
         end;

   for i := 1 to 5 do
      writeln(i,': ',a[i]);
end.

2D arrays

Arrays can have 2 dimensions instead of just one. In other words they can have rows and columns instead of just rows.

 123
1123
2456
3789

Here is how to declare a 2D array:

program Arrays;

var
   a: array [1..3,1..3] of Integer;

begin
end.


To access the values of a 2d array you must use 2 numbers in the square brackets. 2D arrays also require 2 loops instead of just one.

program Arrays;

var
   r, c: Integer;
   a: array [1..3,1..3] of Integer;

begin
   for r := 1 to 3 do
      for c := 1 to 3 do
         Readln(a[r,c]);
end.


You can get multi-dimensional arrays that have more than 2 dimensions but these are not used very often so you don't need to worry about them.