Archive for the ‘Uncategorized’ Category

LDTP Editor

Posted by sp2hari

Want to use LDTP to test your application? Or do you want to automate the actions you do often? Or are you a GNU/Linux user who want to show “magic” to your friends by recording your actions and playing them back? You can use LDTP for this. But one small issue with LDTP is that you should know the LDTP Python API to write any test suite. But with the new LDTP Editor, this makes your job really simple. A screenshot of the LDTP Editor is shown below.

 

LDTP Editor

 

This is a simple HOWTO for recording and playing back the recorded script.

Installing LDTP.

  • Download the lastest LDTP source code from http://people.freedesktop.org/~nagappan/ldtp-0.9.2.tar.gz.
  • Uncompress the file.
  • Compile the code using ./configure and make
  • If you don’t have the access to install softwares, run the ldtpeditor file in the python folder
  • If you have access to install softwares, then run “make install”

Note:: After installing LDTP Editor, i when i tried to run ldtpeditor, got an error saying

hari@hari-laptop:~/ldtp/ldtp-0.9.2$ ldtpeditor
(ldtpeditor:11130): libglade-WARNING **: could not find glade file '/usr/share/local/ldtp/glade/ldtpeditor.glade'
Glade file not found

The ldtpeditor.glade file is present in the python folder. I got this error because i compiled the code as ./configure. If i had done it as ‘./configure –prefix=/usr’, then i wouldn’t have got this error. Anyway i copied the file manually to that folder.

hari@hari-laptop:~/ldtp/ldtp-0.9.2$ sudo mkdir -p /usr/share/local/ldtp/glade/
hari@hari-laptop:~/ldtp/ldtp-0.9.2$ sudo cp python/ldtpeditor.glade /usr/share/local/ldtp/glade/
hari@hari-laptop:~/ldtp/ldtp-0.9.2$ ldtpeditor

After that when i ran ldtpeditor, it ran without any issues.

Recording using LDTP Editor

For this let us consider recording the actions performed in gcalctool.

  • First make sure Assistive Technology is enabled in your desktop. If you are not sure about this, open gnome-control-center and in that open Assistive Technology Preferences. You should have Enable Assistive Technologies checked to use LDTP.
  • If you are enabling Assistive Technology only now, logout and login again.
  • Run ldtpeditor and gcalctool.
  • Make sure both you have enabled ‘Always on Top’ or both the applications and both the window doesn’t overlap with each other.
  • Click the Start button the LDTP Editor. All actions performed after this are recorded.
  • Perform actions in the gcalctool. Check out this video to see the actions i recored in my computer .
  • After you’re done with the actions in the gcalctool, click the Stop button in the LDTP Editor.
  • You can see that the ‘Recorded Code’ tab is updated with code as when you perform actions in gcalctool.
  • Click the convert button in the LDTP Editor. You’ll see that the Generated LDTP Code and Generated LDTP XML tabs are filled with generated code.
  • The Play button is not working now. I wrote the patch for that yesterday night ;-).
  • Save the contents of the ‘Generated LDTP Code’ into a python file (for ex frisco.py) . Note that if the file name you specify already exists, then it OVERWRITES the filename without any warning.
  • Then run hari@hari-laptop:~$ python frisco.py
  • The actions you performed while recording will be played back again :-)

Currently the Play button in the LDTP Editor is not enabled. But you can make it work by applying the patch mentioned below. I guess this patch will be added to LDTP Editor in a week or so. So check the ChangeLog file before applying the patch.

LDTP Editor Preferences

Using the LDTP Prefereces, you can control what all actions you can control. A brief summary about the options given in the Preferences window.

  • Listen key events
    This option is not yet implemented. Checking/Unchecking this doesn’t make any difference now.
  • Listen mouse events
    This option is not yet implemented. Checking/Unchecking this doesn’t make any difference now.
  • Generate LDTP Code
    Only when if this option is enabled, Convert will generated to LDTP code in the ‘Generated LDTP Code’ tab. This is enabled by default when you run LDTP Editor.
  • Generate Data XML
    If this option is enabled, the LDTP Editor will generate data XML for the actions you perform.
  • Generate keyboard events code
    Generates code for the keyboard events you performed during the recording session.
  • Generate wait time code
    Calculates the delay one takes between each action during the recording session and generates code so that similar time delay is generated while play back.
  • Generate Memory / CPU statistics.
    The code to generate Memory and CPU statistics will be generated. You need to install pystatgrab and libstatgrab packages.

Patching to make the Run button work

  • Copy this patch file to your ldtp folder.
  • Runhari@hari-laptop:~/ldtp/ldtp-0.9.2$ cd ldtp-0.9.2
    hari@hari-laptop:~/ldtp/ldtp-0.9.2$ patch -p0 < ldtpeditor_runbutton.patch
  • Compile the code again and run ldtpeditor. This time after you Convert the Code, you can Run the code from the LDTP Editor. :-)

Note:: The generated code had many unwanted waittillguiexist. I saw waittillguiexist(”dlg0″) in many places. If your playback is stopped because of this, remove that before running the scripts.
Sometime the resource will go high as the application map info is collected from the application, so no need to worry.

If you find any issues regarding LDTP Editor, report it to ldtp-dev@lists.freedesktop.org or nagappan@gmail.com or sp2hari@gmail.com

All patches are welcome. :-)

Photolog…

Posted by sp2hari

Deer

A picture is worth a thousand words. Yes it is.

Gedit Plugin

Posted by sp2hari

In this article, we’ll see how to write plugins for Gedit. Since plugin development is easy in Python, I’m planning to explain this using Python.

When the first caveman programmer chiseled the first program on the walls of the first cave computer, it was program to paint the string “Hello, world” in Antelope pictures. Roman programming textbooks began with the “Salut, Mundi” program. I don’t know what happens to people who break with this tradition, but I think it’s safer not to find out. So we’ll also deal only with HelloWorld in our first plugin.

This plugin is going to do two things. One is to add the string “HelloWorld ” at the cursor position. The next is to convert all “Hello” in the program to “World”. A neat tutorial to write python plugins is can be found at live.gnome.org. Though you can skip that tutorial for now since I’ve explained most of the things one need to know to write this plugin. But i suggest you read that tutorial soon.

Some of the paths you need to know for writing a plugin.

Path Details
/usr/lib/gedit-2/plugins/ System-wide plugins directory
~/.gnome2/gedit/plugins/ User Plugins directory
/usr/share/gedit-2/ Data needed for system-wide plugins.
~/.gconf/apps/gedit-2/ Gedit configuration.
Can be modified using gconf-editor.
/usr/share/gtk-doc/html/gedit gedit Reference Manual

Every python plugin needs at least two files. Let us name our plugin as “frisco”. So we should have two files namely, frisco.gedit-plugin and frisco.py

Let’s start with the contents of frisco.gedit-plugin.
[Gedit Plugin]
Loader=python
Module=frisco
IAge=2
Name=HelloWord
Description=A HelloWorld plugin for Gedit.
Authors=Harishankaran K <sp2hari@gmail.com>
Copyright=Copyright © sp2hari
Website=http://www.sp2hari.com

The contents of this file is almost same for all the plugins. The module, name and description will change for different plugins. If your plugin has the python file frisco.py, then the modulde is frisco.

Note :: We don’t specify the extension in the module name.

The .gedit-plugin file is done now. Next let’s move on to frisco.py.

#!/usr/bin/python

import gedit

class HelloWorldPlugin(gedit.Plugin):
    def __init__(self):
        print "Plugin loaded"

    def activate(self, window):
        print "Plugin activated"

    def deactivate(self, window):
        print "Plugin deactivated"

    def update_ui(self, window):
        pass

This file, frisco.py derives one class from the Gedit.plugin and defines activate, deactivate and update_ui. activate() is called when the plugin is activated. Similarly deactivate() is called when the plugin is deactivated. We will check how our plugin works now.

Run gedit from terminal and check whether your plugin is listed in the plugins list.

You can see that the details you provided in frisco.gedit-plugin can be viewed in the About Plugin and the Credits.

Now enable the plugin and look at shell prompt. You will see the print statements being execute when we activate and deactivate the plugin. :). Wow, our first plugin is ready to add more spice. :-)

Note:: If you get an error saying

WARNING **: Cannot load Python plugin ‘HelloWord’ since file ‘frisco’ cannot be read.

WARNING **: Error activating plugin ‘HelloWord’

Then the file frisco.py is not present in your plugins directory or the python file has an error. Fix the code and try again. You will get the output as shown below.

Frisco Plugin

 

The output for the above plugin in the shell when the plugin is activated and deactivated for a few times will be like


hari@hari-laptop:~$ gedit
Plugin loaded
Plugin activated
Plugin deactivated
Plugin activated
Plugin deactivated
Plugin activated
Plugin deactivated
Plugin activated

Now we have to add functionality to this plugin. A good practice while coding plugin is the create a separate ‘Helper’ Class which will control the window and do all useful actions. It’ll be called once in the main class.

So we will modify the HelloWorldPlugin class as follows

#!/usr/bin/python

import gedit

class HelloWorld(gedit.Plugin):
    def __init__(self):
        gedit.Plugin.__init__(self)
        self._instances = {}

    def activate(self, window):
        self._instances[window] = HelloWorldHelper(self, window)

    def deactivate(self, window):
        self._instances[window].deactivate()
        del self._instances[window]

    def update_ui(self, window):
        self._instances[window].update_ui()

The code for the HelloWorldHelper class will be



class HelloWorldHelper:
    def __init__(self, plugin, window):
        print "Plugin created for", window
        self._window = window
        self._plugin = plugin

    def deactivate(self):
        print "Plugin stopped for", self._window
        self._window = None
        self._plugin = None

    def update_ui(self):
        # Called whenever the window has been updated (active tab
        # changed, etc.)
        print "Plugin update for", self._window

When you run gedit from terminal, now, it will print more details like the Gedit window object. A sample run for the above code is given below

hari@hari-laptop:~$ gedit
Plugin created for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin update for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin update for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin stopped for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin created for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin stopped for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin created for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin stopped for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>
Plugin created for <gedit.Window object at 0x8521504 (GeditWindow at 0x816e000)>

Hereafter there is no need to change the HelloWorldPlugin class. So we’ll work only on the HelloWorldHelper class. We will define a ui_str which will enable us to add a menuitem in the Tools menu.

We will define the ui_str as follows

import gtk 

ui_str = """<ui>
  <menubar name="MenuBar">
    <menu name="ToolsMenu" action="Tools">
      <placeholder name="ToolsOps_2">
        <menuitem name="Insert HelloWorld" action="InsertHelloWorld"/>
        <menuitem name="Change Hello to World" action="ChangeHellotoWorld"/>
      </placeholder>
    </menu>
  </menubar>
</ui>
"""

The activate, deactivate and update ui functions for the HelloWorldHelper Class are modified as follows

    def __init__(self, plugin, window):
        self._window = window
        self._plugin = plugin

        # Insert menu items
        self._insert_menu()

    def deactivate(self):
        self._window = None
        self._plugin = None

        self._remove_menu()
    def update_ui(self):
        # Called whenever the window has been updated (active tab
        # changed, etc.)
        self._action_group.set_sensitive(self._window.get_active_document() != None)

Now we need to write the method insert_menu which will register the callbacks for the actions like inserting hello world and changing hello to world.
The insert_menu function is defined as followed. If you know gtk or pygtk then it’ll be easy for you to understand that code. I’ll advise you to read the basics of pygtk if you plan to write your own plugin.

    def _insert_menu(self):
        # Get the GtkUIManager
        manager = self._window.get_ui_manager()

        # Create a new action group
        self._action_group = gtk.ActionGroup("ExamplePyPluginActions")
        self._action_group.add_actions([("InsertHelloWorld", None, _("Insert HelloWorld"),
                                         None, _("Insert HelloWorld"),
                                         self._inserthelloworld)])
        self._action_group.add_actions([("ChangeHellotoWorld", None, _("Change Hello to World"),
                                         None, _("Change Hello to World"),
                                         self._hellotoworld)])

        # Insert the action group
        manager.insert_action_group(self._action_group, -1)

        # Merge the UI
        self._ui_id = manager.add_ui_from_string(ui_str)

    def _remove_menu(self):
        # Get the GtkUIManager
        manager = self._window.get_ui_manager()

        # Remove the ui
        manager.remove_ui(self._ui_id)

        # Remove the action group
        manager.remove_action_group(self._action_group)

        # Make sure the manager updates
        manager.ensure_update()

Now we are all set the two final functions which will do the required actions. These are defined in the helper class as follows

    def _hellotoworld(self, action):
        doc = self._window.get_active_document();
        if not doc:
            return
        doc.replace_all("Hello", "World", 0);

    def _inserthelloworld(self, action):
        doc = self._window.get_active_document();
        if not doc:
            print "Noe";
            return;
        doc.insert_at_cursor("HelloWorld")

Well, that’s all. Your first plugin is up and running now :-) :-)

The python files used in this example can be downloaded here.

External Tools

Posted by sp2hari

 

Often you would like to have a feature in gedit like, Compile when F7 is pressed, Compile and Run when F8 is pressed and more and more. One simple (grrr…) solution for this is to write our own plugins. But to write a plugin for gedit in python, you need to know pygtk and of course python. A simple linux user need not know all these and hence will go for some other editor which provides these features. External Tools is a plugin which enables you to make gedit do anything. Yeah ANYTHING.

The great news is that External Tools plugin is comes with the gedit. So no need to download or install anything. Just Enable the External Tools plugin and you can configure the plugin either by clicking Configure Plugin in the Plugins tab or choosing Tools -> External Tools… from the menu bar.

 

Gedit External Tools

 

Gedit menu

 

The External Tools manager window is the place where you add your custom scripts. The manager window looks like,

External Tools Manager

As you can see, every tool has a
Name: A unique string to identify itself
Description: A small description about your tool
Shortcut Key: Set the keys to be pressed so that the tool is run
Commands: The actual commands
Input: Input from the current tool
Output: What to do with the output of the tool
Applicability: To what documents is this tool applicable.

Now let us write a simple tool to compile a C/C++ program when Control F7 is pressed. We’ll assume that the filename ends with .c or .cpp extension and there is no ‘.’ in the filename.

  • Click the New Button in the External Tools Manager
  • Rename the New tool to ‘Compile C/C++ Code’
  • Change the Description to ‘Compiles the C/C++ Program when Ctrl F7 is pressed.
  • Click in the shortcut key region and press Control F7. This sets the shortcut key for this tool as Control F7.
  • Paste this code in the Commands

#!/bin/bash
# Store the file name in a variable
FILE_NAME=$GEDIT_CURRENT_DOCUMENT_NAME
# Check if file extension is .cc
if [ `echo $FILE_NAME | cut -d "." -f 2` = "cc" ]
then
FILE_NAME_LEN=`expr ${#FILE_NAME} - 3`
FILE_NAME_BASE=${FILE_NAME:0:$FILE_NAME_LEN}
make $FILE_NAME_BASE
fi
# Check if the file extension is c
if [ `echo $FILE_NAME | cut -d "." -f 2` = "c" ]
then
FILE_NAME_LEN=`expr ${#FILE_NAME} - 2`
FILE_NAME_BASE=${FILE_NAME:0:$FILE_NAME_LEN}
make $FILE_NAME_BASE
fi
exit 0

  • Set the Input to ‘Nothing’
  • Set the Output to ‘Display in bottom pane’
  • Set the Applicability to ‘All Documents’

Before we explore the code, let us see a few useful variables which can be used in the commands region
$GEDIT_CURRENT_DOCUMENT_URI
$GEDIT_CURRENT_DOCUMENT_NAME
$GEDIT_CURRENT_DOCUMENT_SCHEME
$GEDIT_CURRENT_DOCUMENT_PATH
$GEDIT_CURRENT_DOCUMENT_DIR
$GEDIT_DOCUMENTS_URI
$GEDIT_DOCUMENTS_PATH

As you can see, the last two variables are applicable when you do some action for all the tabs opened. Since we are interested in compiling only the current tab, we need to use only $GEDIT_CURRENT_DOCUMENT_NAME.
For a file named deer.txt in my home(/home/hari/) directory, the variables are set as

Variable Name Value
$GEDIT_CURRENT_CURRENT_DOCUMENT_URI file:///home/hari/deer.txt
$GEDIT_CURRENT_CURRENT_DOCUMENT_NAME deer.txt
$GEDIT_CURRENT_CURRENT_DOCUMENT_SCHEME file
$GEDIT_CURRENT_CURRENT_DOCUMENT_PATH /home/hari/deer.txt
$GEDIT_CURRENT_CURRENT_DOCUMENT_DIR /home/hari
$GEDIT_CURRENT_DOCUMENTS_URI file:///home/hari/deer.txt
$GEDIT_CURRENT_DOCUMENTS_PATH /home/hari/deer.txt

The script is pretty obvious. It takes the file name (say deer.c) and cuts the file name using ‘.’ as the seperator. If the second field is c, then it removes the last two characters in the file name (which gives deer) and compiles it using the make command.

That gives us so much possibilties with gedit. You can compile, compile and run a C/C++ script, run a PHP, Perl, Python within your gedit.

If you don’t know how to write shell scripts don’t panic. Any other language like python, perl, php will run there. You can also share the tools files with your friends :) :). All you need is the tools folder in ~/.gnome2/gedit/. A zip file of my tools folder can be downloaded here. It contains scripts to

  • Compile C/C++
  • Run C/C++/Python/PHP/Perl/Shell/
  • Check PHP Syntax
  • Indent the current file

There are few things which External Tools can’t do. Like changing only a specific text in the buffer. You need to write your own plugin for those compicated issues. If you’re planning to write a plugin for gedit, check out the next post which explains about a simple HelloWorld Plugin which replaces all ‘Hello’s in the text by ‘World’.

Gedit

Posted by sp2hari

Every GNU/Linux user must be knowing about Gedit. This tiny text editor which comes with gnome is much more powerful than we all think. A few customizations and adding a few plugins will convert this simple text editor into a complete IDE for any programming language. In this article, i have mentioned about the configurations i have made in my box and the plugins which you might find useful.

Any text editor has to be customized according to the need of the end user. The customizations for a C or C++ coder and a PHP or Python coder are totally different. So let me write here according to various needs. Check out in which category you fit in and use those customizations.

The Preferences window in Gedit is the core which converts this simple text editor into a complete IDE. It has features to customize almost everything.

Gedit Preferences

General Configurations

Open Preferences Window (Edit -> Preferences)

In the View Tab

  • Check Enable text wrapping.

I prefer to see the long lines in the same window, which reduces the pain of scrolling across the window using the mouse.

  • Check Display line numbers.
  • Check Highlight current line

In my Ubuntu Studio theme, it wasn’t easy to read when the current line is highlighted. So i disabled this in that theme. So check this whether this suits your gnome theme when you enable this.

  • Highlight matching bracket

An useful option if you are used to getting confused with brackets.

In the Editor Tab

  • Set the Tab width as 4
  • Check Enable automatic indentation
  • Uncheck Create a backup copy of files before saving

Again this depends upon your need. Backup files are created by adding a ‘~’ to the current file name. If you are a web developer and coding in any web development language, better don’t enable this option. Many times these ‘~’ files created might create a security hole in your server. For example, mysql_connect.php file will have a backup called mysql_connect.php~ and your web server will parse the mysql_connect.php but it won’t do the same for the backup file. It’ll just display the source code to the client and thereby your your mysql password is gone :P

  • Check Autosave files every 5 minutes and make that 2 mins

If you don’t have the habit of saving the file often, then this might save you when something terrible happens :P

In the Font & Colors Tab

  • Uncheck the Use the system fixed width font
  • Set the size of the editor font as 10 or 12
  • Choose any one font from the following. Note that Mono space 10 is the system fixed with font.

Standars Symbols L
Serif
Vemana
Sans
Monospace
Mallige Normal
Loma Book

  • I prefer the Classic color scheme. Just three more clicks, you can see all the color scheme and choose anything you like.

In the Plugins Tab

 

Gedit Plugins

This sections makes the gedit a really powerful text editor. By default gedit comes with few standard plugins but you can install more plugins by installing the gedit-plugins package. If you don’t have root access, download the plugins from gedit.org and copy it to your ~/.gnome2/gedit/plugins folder. You can continue if you are lazy to download the plugins now. You can do that when a need arises. ;)

After this jump to section which you might be interested in.

Programming

  • Bracket Completion ( You need to install this plugin)

A plugin which automatically adds closing brackets, single quotes and double quotes. Sometimes really useful and sometimes irritating. When you are typing the code, this is pretty useful but when you are editing a code already written, then this irritates you by adding closing brackets or quotes where you never intended to add.

  • Code Comment ( You need to install this plugin)

A useful plugin for any programmer. You can comment or uncomment a selected block of code.

  • Indent Lines

Very useful when you are specific about the indentation rules. Indents or un-indents a selected block of code. Very useful for python.

  • Snippets

Want to insert a piece of code which just a few keystrokes, then this is for you. Yes lesser keystrokes than Ctrl C Ctrl V.

  • External Tools

This gives amazing power to manipulate anything within gedit. I guess i can’t write about this here. Check out this post about External Tools. And don’t skip that post. It’s the BEST plugin for gedit.

HTML

Download the HTML tidy plugin from here and extract the folder to your ~/.gnome2/gedit/plugins folder. Enable the HTML Tidy plugin from the plugins tab in Preferences Window. HTML Tidy is an utility to clean up and pretty print HTML/XHTML/XML. Enable the Bottom Pane from the View Menu and you can clean up or check any HTML/XHTML/XML document.

The default configurations are enough to use Tidy. If you want to tweak it according to your needs, then Configure Plugin ( There are so many options :P )

Snippets

This is an useful plugin once you know what gives what. If you code for online programming contests like spoj, topcoder, acm or usaco and if your programming language is C++, then download this cpp.xml file and put it in your ~/.gnome2/gedit/snippets folder. Then press template[tab] or topcoder[tab] in a new cpp file.

Apart from that, if you are a web developer, then check out the Snippets for HTML and PHP. Once you remember the shortcuts which you need, they’ll make your life really easy.

Slice…

Posted by sp2hari

Slice notation is one of the powerful feature in python using which can be used for operations like substr, str_reverse etc etc.

The slice notation is really powerful for strings. I’m not very sure whether it can be used for other data types.

For a string, it can be used as variable_name[start:end:step]

If the start and end are equal, then a null string is returned.
If step is positive and start is greater than the end, then a null string is returned.
If step is negative and start is lesser than the end, then a null string is returned.

Ok. If you are confused about start, end, step, equal, greater. lesser, positive and negative, don’t worry. Things are explained very clearly after this. :-)

First few lines about the step. If the step is positive, then the direction in which the input string is scanned is forward direction. If the step is negative, then the string is scanned in reverse direction. So now i hope you understand why start must be less than end if step is positive. For the same reason, start must be less than end if the step is negative.

Let us see a simple slice example.

>>> i = “Hello World”
>>> i[2:10:1]
‘llo Worl’

So it’s very clear that the basic action of the slice notation is to return a sub string.
In the above example, it returns the characters from the string whose position are equal to and greater than start and less than end.

Note :: The character at position end is not returned.
In the above example i[10] = “d” is not returned.

If the start is not specified and step is positive, then the default value is 0
If the end is not specified and step is positive, then the default value is len(string).
If the start is not specified and step is negative then the default value is len(string).
If the end is not specified and step is negative, then the default value is NOT 0, coz in this case even 0th character is returned.
If the step is not specified, then the default value is 1

So i[::] prints the entire string. In fact, in most cases the step is not specified. So i[:] returns the entire string.

>>> i = “Hello World”
>>> i[::]
‘Hello World’
>>> i[:]
‘Hello World’
>>>

Slice notation can also take negative values.
If the start value is negative, then the last start characters are returned.
If the end value is negative, then the last end characters are not returned.

So if both start and end values are negative, then the absolute value of start must be greater than the absolute value of end. Else a null string will be returned.

>>> i = “Hello World”
>>> i[-5:] #Start is -ve. So last 5 characters
‘World’
>>> i[:-5] #End is -ve. So everything except last 5 characters
‘Hello ‘
>>> i[-8:-3] #Start is -8. =>”lo World”. In this don’t include last 3 characters => “lo Wo”
‘lo Wo’
>>>

The real fun is when even step is negative.
If the start is greater than the end, then the step must be -ve, which makes the string to be returned as reverse.

So consider this example.
>>> i = “Hello World”
>>> i[8:4:-1]
‘roW ‘
>>>

In the above example, i[8:4] part refers to i[8] and i[4] positions and since the step is negative, now it returns characters at i[8], i[7], i[6], i[5]. Note that even here i[4] is not returned.

Finally, if step is something other than 1, then every stepth character is returned. For example
>>> i = “Hello World”
>>> i[::2]
‘HloWrd’
>>> i[::-2]
‘drWolH’
>>>

Any idea why i wrote this post.

Saw this small snippet for string reverse in python

>>> a = “Hello World”
>>> print a[::-1]
dlroW olleH
>>>

Sweet and cute na. ;-)

To know more about slice notation you refer to the python python doc.

Finally 10….

Posted by sp2hari

Ok, i am certainly not talking anything about my GPA. After fighting (fighting is an understatement i suppose) with Firefox and LDTP for 3 hours (well this is actually few days), finally managed to get 10 test cases work properly.

At least these 10 test cases will work properly for integration with Tinderbox. Have to send these test cases to emily soon and get them integrated with tinderbox.

The output log is
<ldtp>
<group name=”group1″>
<script name=”verifyaddressfield.py”>
<test name=”address field and go button”>
<pass>1</pass>
</test>
</script>
<script name=”verifybackforward.py”>
<test name=”Back and Forward buttons”>
<pass>1</pass>
</test>
</script>
<script name=”verifyhome.py”>
<test name=”verify home button”>
<pass>1</pass>
</test>
</script>
<script name=”verifynewtab.py”>
<test name=”Open a new tab “>
<pass>1</pass>
</test>
</script>
<script name=”verifyyahoo.py”>
<test name=”topsite - yahoo”>
<pass>1</pass>
</test>
</script>
<script name=”verifymsn.py”>
<test name=”topsite - msn test”>
<pass>1</pass>
</test>
</script>
<script name=”verifyamazon.py”>
<test name=”topsite - amazon”>
<pass>1</pass>
</test>
</script>
<script name=”verifyftp.py”>
<test name=”navigate ftp”>
<pass>1</pass>
</test>
</script>
<script name=”verifysearch.py”>
<test name=”Open search by keyboard shortcuts”>
<pass>1</pass>
</test>
</script>
<script name=”verifyfindinpage.py”>
<test name=”Find in Page”>
<pass>1</pass>
</test>
</script>
<timeinfo start=”03:23:00 AM on 18-Jun-2007″ elapsed=”0:1:8″></timeinfo>
<groupsstatus total=”10″ pass=”10″ fail=”0″></groupsstatus>
</group>
</ldtp>

Well looks like i have underestimated how bugs can trouble a poor coder like me :P.

Each test case has its unique problem :P.
The major problem is the Firefox crash :(. Though the test case work individually, Firefox crashes if all the test cases were run under a single runner xml :-(. I have downloaded Firefox firefox-3.0a6pre now ( was using firefox-3.0a5pre all these days). Hopefully Firefox 6 is stable against the test cases :-).

Anyway the 10 is not the final list. I am supposed to test 30 test cases properly for the Functionality subgroup of smoketests testgroup for Firefox 3.0. Not to mention about the lots and lots of test cases from other test groups.

Let me post the issues i am facing with the other test cases, so that it is easier for me to fix them later.

Before that, the 10 test cases which worked in my favour are :)

3954: Address Field and Go button
4032: Back and Forward buttons
4031: Home button
4086: Open a new tab
3955: Top Site - Yahoo
3956: Top Site - MSN
3957: Top Site - Amazon
3959: Navigate FTP
4245: Open search by keyboard shortcuts
3967: Find in Page

The test cases having issues are
1. 4137: Add an RSS feed/Livemark
This is the strangest test case i have ever found :(. This doesn’t work for the first time. Next time without any modification, if i run the test case it works like properly. Third time it is not working and fourth time it again works properly . Well, that is more than enough for me, i either end up banging the computer monitor or beating myself that there is no 5 th time :-(. Should check this test case properly.

Looks like this is the only test case which troubles me as of now. Have the rest of the code ready but looks like new problems are starting soon. For the same runner xml, same files , same Firefox, test case 2 shows come error. Have to check that soon. Got firefox-3.0a6pre few mins back. Have to run the test cases with that.

And yes, tried something with the list not getting selected problem. Even nags confirmed this problem some time back and finally able to find out the exact line where the error occurs .

if (AccessibleSelection_selectChild (selection, text_index)) { }
That is line 110 from list.c. The if statement is returning false ending up in “LDTP_ERROR_UNABLE_TO_SELECT_CHILD” . Hoping to fix this soon. Will be really happy if i fix this one as i will be able to add something to the ldtp source code. Been a long time since my name appeared in the Changelog ;-) ;-)

Only thing i am happy about is both Ubuntu Linux and Solaris responds similarly for the test cases. So no separate Firefox issues and Solaris issues as of now. Let us see how this proceeds.

Another small issue.
Whenever i get any error in any of the test cases, i get the following error
<script name=”verifyamazon.py”>
<test name=”topsite - amazon”>
<ERROR>Traceback (most recent call last):
File “/usr/local/bin/ldtprunner”, line 407, in executescript
execfile (scriptname, scriptglobal)
File “verifyamazon.py”, line 52, in <module>
log (msg, ‘error’)
File “/usr/local/lib/python2.5/site-packages/ldtp.py”, line 2500, in log
logger.error (message)
File “logging/__init__.py”, line 1015, in error
File “logging/__init__.py”, line 1100, in _log
File “/usr/local/lib/python2.5/site-packages/ldtp.py”, line 2421, in makeRecord
return LdtpLogRecord (name, level, fn, lno, msg, args, exc_info)
File “/usr/local/lib/python2.5/site-packages/ldtp.py”, line 2394, in __init__
msg = ‘<’ + logging.getLevelName (level) +’>’ + saxutils.escape (msg) + ‘</’ + logging.getLevelName (level) + ‘>’
File “/usr/lib/python2.5/site-packages/_xmlplus/sax/saxutils.py”, line 31, in escape
data = data.replace(”&”, “&amp;”)
AttributeError: ‘LdtpExecutionError’ object has no attribute ‘replace’
</ERROR>
</script>

I am giving the error message properly in the try block, but not in the except block. When i give the error in the except block then i get the error message in the log file properly. But i am supposed to pass the error message from the try block to the except block. Should learn a bit of python exceptions to know more about this

Anyway the files for the test cases which are working can be obtained from here

Note :: Have added many more test cases to the above file now, but didn’t like to change the title.

PODWORKS.in

Posted by sp2hari

India’s Biggest Event on Audio & Video Podcasting

Date: June 9 & 10 (Saturday & Sunday)

Venue: Tidel Park Auditorium, Chennai.

Cost: Rs.200

Alagappan designed banners saying I’m Attending Podworks.in and I’m speaking at Podworks.in. You can grab those here.

PodWorks is an ideal place to learn how to start your own podcast or to discover the latest tips and tricks for taking your show to the next level. The presentations offered will cover the whole spectrum from content production, technical how-to, business podcasting, marketing and monetization. Each session is an exchange of ideas.

I am really looking forward for this event, coz apart from the podcasting , it will be a re-union kind , where i will be meeting alagappan :) :) . Infact that’s the main reason why i am attending this ;-)

You can register here and make the event a big success :)

Hello World …

Posted by sp2hari

I love Hello World programs.
The reason is simple. Whenever i code a hello world, it means i am learning something new. I once found a huge collection of hello world programs here.

And yes, i did a hello world program today. It is related cluster programming using MPI . :-) .

The code for the hello world

#include <stdio.h>
#include <mpi/mpi.h>
int main(int argc, char *argv[]) {
int err;
err = MPI_Init(&argc, &argv);
printf (”Hello World\n”);
err = MPI_Finalize();
}

Since i dont have a cluster at home, i had to simulate a cluster. That can be done using the mpirun command .

hari@home:~/spider/cluster$ mpirun -np 3 a.out
Hello World
Hello World
Hello World
hari@home:~/spider/cluster$

For the first time, this asked for my password 3 times ( the number of process i mentioned ) . After that i created a keygen for myself and then things went fine . But it took a long time when i gave the number of processes as 100 .

Planning to code for a fractal using MPI in my free time :) .

The meeting starts at 8 ….

Posted by sp2hari

“Punctuality is the art of guessing how late the other fellow is going to be “
I have admired this quote many a times . :-) :-) . Infact it is one of my fav .

Today i got a message saying
“Hey..Dulta meeting today.. At 8pm .. Sun Lab ..Every1 must come.. So be there.. !

Being confused about whether i am a dulta member or not, i finally decided to attend this meeting . Not because i decided to work dulta, neither i am afraid about chucked out of dulta , but i was jobless and anyway i will be in SUN lab working for my SOC. So i did not mind attending the meeting .

But things went really great . I never realised that the 8 PM is “dulta’s 8 PM” . And just today i came to know that there is a timezone difference of 30 minutes between IST and Dulta’s Time :) :)

I went to sun lab at around 7.45 (foolish me) and started coding for LDTP in the SUN systems. Yazhini,
Padmini and Deepak Kumar Jha came there on time (all three compsci’s ) . Some 10 mins after that , Nitin (a prod guy ) came to me asking whether there was a dulta meeting there or not ? .

I was really really curious to know who sent that message. I really hoped that DK sent that message ( he was the only senior present there ) . But seems he did not send that message . Finally i asked yazhini and padmini not to waste their time and they went back to their hostel by 8.30 . DK also went to room saying that he has to finish his English report.

Finally “the man” who sent that message came exactly at 8.35 :) :) . I expected him to say a sorry to the members waiting there . But again i was surprised to see him to start directly as
“Ok everyone check http://dulta/info and i want it to be nitt.edu by tonight . Think we have to work tonight blah blah blah blah …”.

I also like this quote
If I have made an appointment with you, I owe you punctuality, I have no right to throw away your time, if I do my own.
Richard Cecil

I really wish these people learn this someday soon .
But yes , i learnt some new stuff from this strange experience .
1. Dulta is always waste of time.
2. Never ever make anyone wait for you.


FireStats icon Powered by FireStats