Ransford Okpoti's Blog

21 October, 2016

A Seamless “Move” To Transfer Money Between Mobile Wallets In Ghana Is Now Possible

Filed under: Uncategorized — ranskills @ 2:32 pm

A company that is silently making waves in the mobile financial services sector in Ghana has taken the bold step by coming out with a solution that every mobile money user would be dying to have, i.e. the ability to transfer money between the various mobile money operators (MMO) in the country.

What it simply means is that you can “Move” – and by the way, that is the name of the service – money from one MMO to another, e.g., transfer money from MTN Mobile Money wallet to an Airtel Money wallet or a Tigo Cash wallet. The good thing about it is that you don’t need a special application to access the service, it can be accessed on any mobile phone through the use of an Unstructured Supplementary Service Code (USSD) service shortcode, i.e. by dialling *718*2# on the mobile phone.

The How

  1. Just dial *718*2# and follow the prompts

Supported Networks

  1. MTN
  2. Tigo
  3. Airtel
  4. Vodafone


Things To Look Out For Before Using The Service

  1. How much does it cost to transfer money between wallets? Is it cheaper than the alternatives currently available using the electronic voucher system?
  2. Will the charges that apply be shown to you before transferring the money?
  3. If a transfer was not successful, but money has been taken from the sender’s wallet:
    1. Who do you complain to?
    2. How long should you expect for the refund of the money? This should be explicitly stated in the Terms & Conditions of the service.


“Move” is a much-welcomed service in the mobile money space and will go a long way to add a nice convenience in moving money between mobile wallets provided by different operators.


13 August, 2016

A Regular Expression (RegEx) To Match Integers and Doubles

Filed under: Java, JavaScript, Programming — ranskills @ 6:05 am

These regular expressions matches both the positive and negative variations of the data types specified below

  • integers – e.g., 1, 89, 81223, -7, etc.
  • floating point numbers (doubles or floats) – e.g., .0, 59.3, 300.12, -.87


The adopted approach was to avoid nested expressions which is not needed if it is only the number that is of interest and not its components like the decimal part and the fractional part.


var numberRegex = /(\-?\d*\.?\d+)/;

// Testing
var testNumber = "-45.8974";



String numberRegex = "(\\-?\\d*\\.?\\d+)";


Coming soon.



The site below allows the building and testing of regular expressions online, it is really nice with some colour coded tags and parenthesis colour matching to make a really complicated regular expression bearable to spot errors.



31 July, 2016

Forcing Maven To Use The Local .m2 Repository

Filed under: Java — ranskills @ 6:54 am

If each Maven run on a project results in always downloading dependency jars even though they have already been downloaded and stored in your local .m2 repository which is by default located at USER_HOME/.m2 e.g., on my Windows 10 machine, mine is C:\Users\ransk\.m2, then you only have to instruct Maven to operate in an offline mode.

One way to do is to locate the main Maven install directory, this is referred to as the MAVEN_HOME, which contains the settings.xml file in the conf directory, e.g. E:\tools\apache-maven-3.3.9\conf\settings.xml.

The offline settings is off by default and it only has to be turned on by ensuring you have the entry below in the settings.xml file.


With this in place, Apache Maven will check to see if required dependencies are available locally before contacting any remote repositories.

19 March, 2015

Import An Oracle Dump File

Filed under: Database — Tags: — ranskills @ 7:40 pm

These are the steps I normally follow when restoring Oracle dump files for the purposes of my work.

I prefer to logically keep the restored entities logically and physically separate through the use of tablespace and associated datafile(s) respectively.


Create and assign the user to the earlier defined tablespace.


If I want the created user to log in to the database, the statement below is executed.


And now to the import part,

Oracle Dump Log File With Highlighted User

IMP system/[password here] IGNORE=Y FROMUSER={...} TOUSER=xxx FILE=path_to/file.dmp;

In the sample above, the FROMUSER will be SA

8 February, 2015

This is not an ACL project Problem, My Solution

Filed under: ACL Analytics — ranskills @ 9:36 am

I was greeted by the unpleasant message “This is not an ACL project” from a dialog box after I tried opening an ACL Analytics 11 project and had selected Working from the earlier dialog box that welcomed me when I opened the project.

ACL Analytics This is not an ACL project

This is a message I haven’t seen before, but I just suspected the ACL project file was somehow corrupted. I quickly searched for solutions online, but not a single search contained my search terms “This is not an ACL project”, even using the almighty Google. Then it dawned on me that it is a problem that hardly happens or people just forget about it and move on.

This is what I tried and worked for me.

  1. I opened ACL Analytics, created a new project in the same location and with the same name as the corrupted project file and confirmed the old file should be replaced.
  2. I opened the log file, by double-clicking on it from the Overview tab or by simply clicking on the Log tab, and selected the entire project history log entries by checking the box beside the Project History root node of the log entries. Right click to copy the scripts from the logs.
  3. I added a script file, through File > New > Script…, you may rename the file Recover from its default name of New_Script, but this is entirely optional. Next, I pasted the log entries into the script file.
  4. Finally, I run the script, answered yes for the old files to be replaced on disk.

This worked for me for a couple of reasons highlighted below.

  1. I had the entire log entries for the project since I had not deleted any entries throughout the inception of the project.
  2. The source data, such as Excel files, I had imported were still at the same locations where I had earlier imported them. As you can obviously imagine, if you did import some files on removable drives and those are not plugged in with the same drive letter assigned by the operating system when following this approach, then you will not have a smooth process as I did.

Good luck recovering your ACL Analytics project.

18 March, 2012

Creating Dynamic Log Files In Zend Framework (ZF)

Filed under: PHP — Tags: , — ranskills @ 11:58 am

The motivation for wanting to do something like this could be any of the following:

  • You want to have separate logs depending on the context (i.e. application, testing, development, etc) in which the application is being run and you do not want to inherit a context and override some values in another context in the configuration file.
  • If your application builds huge log files and, as a result, you want to partition the logs into, say, daily, weekly, monthly, yearly, etc. logs

Below is a typical configuration in the application.ini file.

; Loggers
resources.log.stream.writerName             = "Stream"
resources.log.stream.writerParams.stream    = APPLICATION_PATH "/../data/logs/application.log"
resources.log.stream.writerParams.mode      = "a"
resources.log.stream.filterName             = "Priority"
resources.log.stream.filterParams.priority  = 4

The problem can easily be overcome by adding the highlighted lines to the configuration file, these settings will be used in the bootstrap file to create the log files.

; Loggers
resources.log.stream.writerName             = "Stream"
resources.log.stream.writerParams.stream    = APPLICATION_PATH "/../data/logs/application"
resources.log.stream.writerParams.mode      = "a"
resources.log.stream.filterName             = "Priority"
resources.log.stream.filterParams.priority  = 4

log.path               = APPLICATION_PATH "/../data/logs"
log.partitionStrategy  = "context"
log.partitionFrequency = "weekly"

New Entries Explained

Specifies the location/directory where the files would be created. NOTE: Linux users have to make sure the appropriate read/write permissions are set.
Defaults to context which denotes that log files will be prefixed with the context, or application environment, as is know in ZF, (e.g., production, development, testing , etc.) in which the application is being run.
Specifies when new log files get created and take on any of the following values: daily, weekly, monthly and yearly.

Next, in the Bootstrap.php, add _initLog()function as show below to dynamically create the log files based on the customized settings we provided in the application.ini.
The function simply alters the file name for the Stream logger by appending a unique string to the selected base file name based on the log.partitionFrequency value.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {

    protected function _initLog() {
        $options = $this->getOption('resources');

        $partitionConfig = $this->getOption('log');
        $logOptions = $options['log'];

        $baseFilename = $logOptions['stream']['writerParams']['stream'];
        if ($partitionConfig['partitionStrategy'] == 'context'){
            $baseFilename = $partitionConfig['path'].'/'.APPLICATION_ENV;

        $logFilename = '';
            case 'daily':
                $logFilename = $baseFilename.'_'.date('Y_m_d');

            case 'weekly':
                $logFilename = $baseFilename.'_'.date('Y_W');

            case 'monthly':
                $logFilename = $baseFilename.'_'.date('Y_m');

            case 'yearly':
                $logFilename = $baseFilename.'_'.date('Y');

                $logFilename = $baseFilename;


        $logOptions['stream']['writerParams']['stream'] = $logFilename;

        $logger = Zend_Log::factory($logOptions);
        Zend_Registry::set('logger', $logger);

        return $logger;

21 February, 2012

Talk: Web Scraping, An Important Technique For Data Extraction

Filed under: Uncategorized — Tags: , — ranskills @ 7:14 pm

After the successful launch of Java 7, late last year, here in Ghana by Coders4Africa where I was the main speaker highlighting on the new language changes in Java, I am pleased to announce that I will be making another presentation on Web Scraping at the upcoming meeting.


Web Scraping, An Important Technique For Data Extraction

Introduces Web Scraping using PHP as a valuable alternative to extract data from other websites in the absence of APIs in Africa. Demonstrating how to fetch related data and producing outputs in standard formats such as json, xml, csv, etc.

Event Details

Coders4Africa In Action in Accra Ghana – March 3rd 2012 at BusyInetnet
Saturday, March 3, 2012 from 3:00 PM to 6:00 PM (GMT)
Accra, Ghana

You can register here.
A tutorial will be posted after the event on this blog.

5 February, 2012

Dropping All Tables In A MySQL Database Using A Stored Procedure

Filed under: MySQL — ranskills @ 1:33 pm

Using an engine like InnoDB, which enforces referential integrity through the use of foreign keys, poses a little problem when deleting a table whose field(s) act as foreign keys in other table(s). Dropping an entire database may seem like a convenient approach to use, but will not be an option to users who do not have database creation privileges on the database server, and for those who would want to preserve other objects in the database like views, functions, stored prodecures, etc.

Deleting interconnected tables in a database can be a little frustrating, but the solution is that simple, suppress foreign key checks, if necessary, and delete the tables of interest.
Implementing a solution in the database through the use of a stored procedure is show below.


CREATE PROCEDURE procDropAllTables()

		DECLARE table_name VARCHAR(255);
		DECLARE end_of_tables INT DEFAULT 0;

			SELECT t.table_name 
			FROM information_schema.tables t 
			WHERE t.table_schema = DATABASE() AND t.table_type='BASE TABLE';

		OPEN cur;

		tables_loop: LOOP
			FETCH cur INTO table_name;

			IF end_of_tables = 1 THEN
				LEAVE tables_loop;
			END IF;

			SET @s = CONCAT('DROP TABLE IF EXISTS ' , table_name);
			PREPARE stmt FROM @s;
			EXECUTE stmt;

		CLOSE cur;

Now, let’s drop all the tables by calling our stored procedure as show below.

CALL procDropAllTables();

The above procedure can be tweaked if table deletion is not desired, but should be rather emptied by changing the highlighted line to

SET @s = CONCAT('DELETE FROM ' , table_name);

This is only one of the approaches that could be used to solve the problem, but they all basically work on the same premise that foreign key checks MUST BE disabled.

4 October, 2011

How To Solve MySQL Character Sets and Collations Mixing Problems

Filed under: MySQL — Tags: , — ranskills @ 11:20 am

Character sets and collations enable MySQL to perform comparisons on strings, so if have two or more columns with different character sets and/or collations are used in a way that performs some comparison of some sort on them (either using =, >, <, , a JOIN ON, etc), MySQL will be a little confused and display the error message:

[Err] 1267 – Illegal mix of collations (latin1_danish_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation ‘=’

Unfortunately, there is no single command at the database level that could convert the character sets and collations of all tables within a database. In fact, the only command which appears to get the job done only changes the default values of the character set and/or collation of a database, and does not affect existing tables, but only has effect on new tables to be created.

ALTER DATABASE {database_name} CHARACTER SET {character_set} COLLATE {collation};

Likely for us, there is just a command/syntax for changing these values at the table level, syntax shown below.

ALTER TABLE {table_name} CONVERT TO CHARACTER SET {character_set} COLLATE {collation};


ALTER TABLE employees CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

This problem can be resolved by ensuring that all the tables and their corresponding columns have the same character set and collation. If multiple databases are employed, then they should all have the same character set and collation.
Using the above commands would be a very boring and painful process if you have, say, anything above 20 tables in your database. You will realize that is no fun at all, so we will develop a stored procedure that will automatically iterate through all the tables in the database and sets the character set and collations to our desired values.

The codes for the stored procedure is show below, I presume you can create this in MySQL (If not, jump to the screencast below to see it).

DROP PROCEDURE IF EXISTS procChangeCharSetandCollationForAllTables $$

CREATE PROCEDURE procChangeCharSetandCollationForAllTables()


		DECLARE table_name VARCHAR(255);
		DECLARE end_of_tables INT DEFAULT 0;
		DECLARE num_tables INT DEFAULT 0;

			SELECT t.table_name 
			FROM information_schema.tables t 
			WHERE t.table_schema = DATABASE() AND t.table_type='BASE TABLE';


		OPEN cur;

		tables_loop: LOOP

			FETCH cur INTO table_name;
			IF end_of_tables = 1 THEN
				LEAVE tables_loop;
			END IF;

			SET num_tables = num_tables + 1;

			SET @s = CONCAT('ALTER TABLE ' , table_name , ' CONVERT TO CHARACTER SET latin1 COLLATE latin1_general_ci');

			PREPARE stmt FROM @s;
			EXECUTE stmt;

		CLOSE cur;
	END $$

Once you have the above stored procedure created in the database, just run it as shown below to have all the tables use the same character set and collation which in this case happens to be
COLLATE = latin1_general_ci

CALL procChangeCharSetandCollationForAllTables();

If you prefer to use a different character set and collation, say utf8 and utf8_general_ci respectively, just change the codes in line 23 to

SET @s = CONCAT('ALTER TABLE ' , table_name , ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci ');


11 July, 2011

How To Create a Gherkin Syntax Highlighter In gedit

Filed under: Uncategorized — Tags: , , , , , — ranskills @ 8:29 am

So, I woke up today and did a little bit of surfing, like I always do, and came across Cucumber, a Behaviour-Driven Development (BDD) framework in Ruby and I bought into the idea as it focuses on the behavioural aspects of the system by allowing you to describe and test the system’s behavior. Well, like a typical PHP junkie, I had to look for alternatives in PHP and luckily my search lead me to Behat, a BDD framework in PHP and inspired by Ruby’s Cucumber. Python’s users of Freshen may also find this informative since it uses the same syntax.

I decided to try out the examples only to realize that Gherkin, the Domain-Specific Language (DSL) used to describe the features to be tested in the features file, had no syntax highlighting in gedit, the official text editor of the GNOME desktop environment.

These are steps required to provide a basic gherkin syntax highlighting.


  1. Locate the directory where all the language files used for source code highlighting are kept, i.e. the language-specs directory.


    1. Type the command below to help us locate the language-specs directory.
    2.  locate gtksourceview | grep 'javascript.lang$' 

      The outcome of the above command is shown below with /usr/share/gtksourceview-2.0/language-specs/ as the directory of interest to us.



      The location is going to be either one of these, provided gedit was installed on drive C:\.

    1. C:\Program Files (x86)\gedit\share\gtksourceview-2.0\language-specs (if on Windows 7)
    2. OR

    3. C:\Program Files\gedit\share\gtksourceview-2.0\language-specs
  2. Create a gherkin.lang file into the language-specs directory with the content below.
  3. <?xml version="1.0" encoding="UTF-8"?>
    <!-- Author: 2011 Ransford Okpoti -->
    <language id="gherkin" _name="Gherkin" version="2.0" _section="Scripts">
                <property name="mimetypes">text/x-feature</property>
                <property name="globs">*.feature</property>
                <style id="keyword" 	_name="Keyword"		map-to="def:keyword"/>
                <style id="feature" 	_name="Feature"		map-to="def:type"/>
                <style id="steps_keywords" 	_name="Steps Keywords"	map-to="def:keyword"/>
                <style id="constructors" 	_name="Constructors"	map-to="def:type"/>
                <style id="variables" 	_name="Variables"	map-to="def:comment"/>
                <style id="comments" 	_name="Comments"	map-to="def:comment"/>
                <context id="gherkin" class="no-spell-check">
                            <!-- Keywords -->
                            <context id="steps_keywords" style-ref="steps_keywords">
                            <context id="comments" style-ref="comments" end-at-line-end="true">
                            <context id="feature" style-ref="feature">
                            <context id="constructors" style-ref="constructors">
                            <context id="variables" style-ref="variables">
                            <context id="arguments" end-at-line-end="true">
                                        <context ref="def:decimal" />
                                        <context ref="def:float" />
                                        <context ref="def:string" />
                                        <context id="table_headings">
  4. We are done, close gedit, if you have it opened, and open a gherkin source file with the extension .feature to see the beauty of our work.
  5. NOTE: On line 3, the _section attribute was set to Scripts indicating that the Gherkin menu item can be located from the program’s menu navigation: View -> Highlight Mode -> Scripts -> Gherkin.

Below is a gherkin source file with no syntax highlighting in gedit.

Gherkin File With No Syntax Highlighting

After the completion of our little procedure, you can see how beautiful our gherkin source file appears in gedit.

Gherkin File With Syntax Highlighting

NOTE: The above procedure can be followed to create syntax highlighting for any source file.
For a thorough explanation of the structure of the xml file, follow the official guide.

Older Posts »

Blog at WordPress.com.