Home Classroom

1227

Strings

[You're Ted and you decide to learn some C++ from your friend Barney. This is the eleventh day of the class]

You: Hi, Barney!

Barney: Hi, Ted! You’re real late today.

You: Got a little late. Life’s problems, you know.

Barney: That ain’t a good excuse. Never mind. So what were we doing last time?

You: Mm, we talked about character sequences and you told that we’ll be learning about strings today.

Barney: Fine. First of all, do you know what a string is?

You: A sequence of characters?

Barney: Exactly! The character arrays we talked about last time could also handle such sequences. What do you think is the difference between a normal character array and a string?

You: Mm, not exactly sure, but I think strings are more powerful than usual character arrays.

Barney: Of course. When you deal with arrays, it’s quite difficult to handle them, especially when it comes to characters. The string library has made manipulating character sequences easy. For this, there is a separate data type called ‘string’. Let’s look at an example:

You: So we have to include ‘string’ to use strings?

Barney: Yes, but in some compilers it will work without that too. But it’s safe to include that.

You: Okay.

Barney: As you can see, we have declared a string s and assigned it with the string “Hello there!”. And then we simply printed it. Ain’t that easy?

You: Yeah, so far so good.

Barney: What we saw was a simple string constructor. A constructor is how you initialize a data type, object, etc. There are more than one way of constructing a string, but for the time being, the method we saw will do. Okay, now that we have a string, what kind of things do you think that we may need to do with it?

You: Mmm, to know what the first letter of that string is and to know how many letters there are in that string, etc?

Barney: Yes. For each of the ones you mentioned and many other useful operations there are simple methods in strings. For example, if you need to get the first letter of a string, you consider the string just as an array. So if you want to get the first letter of the string s you would simply..?

You: Type s[0]?

Barney: You’re a real fast learner Ted! Proud of you.

You: Lol

Barney: Right, so you understand that we can access any character in a string like in an array. Now, the second thing you mentioned was finding how many letters there are in a string. For this, the method is simpler. The statement s.length() will give you the length of s.

You: But why the two brackets?

Barney: If you remember correctly, we used such double brackets somewhere else during our journey.

You: Yes, in functions.

Barney: Yes, and there are such functions defined in the string library. Length() is one of them. It returns the length of the string with which you used it. Let’s look at a simple example:

You: I see. It seems strings are very powerful.

Barney: You still haven’t seen the real power of strings. There are several other functions you can use to manipulate strings. Suppose you need to attach one string to the end of another string. What do you think is the way to do that?

You: Mm, supposing the two strings are α and b, we can do something like α=α+b?

Barney: Exactly! It’s as simple as that. Or you can use the append function in the strings library. For example, a.append(b) will do the same trick you just did.

You: I see.

Barney: Now suppose you need to erase some characters off the string. There’s a simple erase function for that. What do you think the statement a.erase(2,5) will do?

You: Erase the characters from 3rd to the 6th?

rd character, 5 characters will be erased.>

You: Ah, okay.

Barney: The command erase has yet another syntax. Suppose you need to erase the characters of the string starting from the 3rd character and until the 3rd from the last. What will you have to do?

You: We can get the length of the string using the length() function we discussed earlier and take away… mmm… 6 from that value and get to know the number of characters we have to delete?

Barney: That’s one possible way. There’s another easier method. You can do the same thing by the statement α.erase(α.begin()+3, α.end()-3).

You: What are those begin and end for?

Barney: They’re called iterators. They give the positions of the first and last characters of the string respectively. So you can understand what that statement does, can’t you?

You: Yes, I get it.

Barney: Good. Now suppose you need to insert some characters into the middle of some string. The function insert comes to the rescue. Its syntax as simple as originalstring.insert(starting pos, string to insert). Let’s look at an example.

As you can imagine, the output of the above is,

You: Hmm, nice.

Barney: So this is only a start. We discussed only a handful of functions we can use to manipulate strings. There’s a lot more functions which you can find in the internet. For example, http://www.cplusplus.com/reference/string/string/ has a listing with explanations and examples. The next time we meet, let’s write a really useful program using what we learned about strings.

You: Okay, thanks a lot. Bye Barney!

Barney: Bye, Ted! By the way, don’t get late the next time!

You: Sure!

1035

Sliding off the usual chattering on Drupal 5, in this article I thought of peeking into Drupal 7, which is the blooming new horizon for Drupal community. The release date of Drupal 7 is whispered in shadows, out of the reach of common mortals but the development snapshots are available for anyone to grab.

[Dries Buytaert - http://buytaert.net/drupal-7-code-freeze-almost-upon-us]

 

Big question – What’s new in Drupal 7

The main difference you will notice might be the way Drupal is interacting with Database. In addition to integrating PDO and better support for multiple Database servers, hook_install, hook_uninstall will now automatically handle schema definitions.

Another awesome addition is how File API accesses files with the use of stream wrappers. All functions that used to take a file path now take a URI like public://old_photos/banana, bringing file paths to a common format. The Drupal 7 core ships with three default stream wrappers namely temp://, public://, and private:// with support for contrib to offer wrappers such as s3:// for Amazon S3, flickr:// for getting data into/out of Flickr and many more. Just this single feature could bring a totally new awesomeness to the Drupal community and much time saving for future Drupal developers.

In terms of field API improvements, taxonomy terms are now fields while comments and taxonomy terms have been made fieldable, and fields are also now translatable which is a go go for Internationalization(I18n) aspect.

Performance-wise, one of the major downfalls of Drupal was the bloated load speed of a default Drupal instance. With D7 this issue has been approached by shipping a “smushed” images that are lighter on bandwidth, and with a caching system to the render API which is currently implemented by blocks, and because it happens early in the page render cycle, it works for both authenticated users and with node access modules.

Another issue that has been fixed in D7 is improvements in Install profile. Instead of .install and .info files working just as identifiers for a module, now they can declare dependencies, manage dependencies, version management and many more.

Regarding Drupal templates, the most exciting improvement might be the addition of wildcards operator in tpl.php files. For example page-user-%.tpl.php to affect any user/xxx while letting page-user.tpl.php affect only the actual page /user could save many unnecessary woes for template designers. Also the AJAX framework from CTools has been brought into the core, and core now supports a new .once() method for ensuring that an AJAX behaviour/effect applies only a single time which can save much code space. Additionally, there are now system-wide classes for marking elements as either completely hidden (.element-hidden: equivalent to jQuery’s hide() function) or invisible (.element-invisible: visible only to screen readers).

Drupal 7 Admin interface [http://www.drupalcoder.com/story/526-drupal-7-whats-new-from-an-end-user-perspective]

 

Is that all ?

No, but listing all new stuff of D7 here would be boring and frankly tiresome to most. But if any one is interested to have a look at all the new changes that will be rolled out with Drupal 7 the best place would be the release note update of D7.

With a development time scope of more than 2 years, the arrival of Drupal 7 is sure to bring much excitement and many new cool features (in addition to the few listed here) to the Drupal community. Till the official announcement, let’s keep fingers crossed!

1467

Layout Overrides: Popup Login Box

Login boxes can take up valuable space on your web site, or just detract from the overall feel of the site. A popular technique for addressing this problem is to show a modal popup login box. The idea is that you replace the page hungry username and password fields with a “login” link that, when clicked, opens a modal popup login box. This can all be achieved out-of-the-box with Mootools and Joomla layout overrides.

In this Joomla development article we will be using two simple layout overrides for the login module and the user component’s login page. Our first step is to create is to copy the native layouts to the layout override folder in the active template.

Copy:
/modules/mod_login/tmpl/default.php

to:
/templates/template_name/html/mod_login/default.php

and copy:
/components/com_user/views/login/tmpl/default_login.php

to:
/templates/template_name/html/com_user/login/default_login.php

Where template_name is the folder name for the default template used on your site. If you use more than one template, linked to menu items, then you will need to create the layout overrides for each template. Your folders should look something like the image to the side.

Open the login module layout override first (/html/mod_login/default.php). Replace the code with the following listing:

<?php // no direct access
defined('_JEXEC') or die('Restricted access'); ?>

<?php if ($type == ‘logout’) : ?>
<form action=”index.php” method=”post” name=”login” id=”form-login”>
<?php if ($params->get(‘greeting’)) : ?>

<div>
<?php if ($params->get('name')) : {
echo JText::sprintf( 'HINAME', $user->get('name') );
} else : {
echo JText::sprintf( 'HINAME', $user->get('username') );
} endif; ?>
</div>

<?php endif; ?>

<div align="center">
<input type="submit" name="Submit" value="<?php echo JText::_( 'BUTTON_LOGOUT'); ?>" />
</div>
<input type="hidden" name="option" value="com_user" />
<input type="hidden" name="task" value="logout" />
<input type="hidden" name="return" value="<?php echo $return; ?>" />

</form>
<?php else :
JHtml::_('behavior.modal', 'a.login');
?>
<script type="text/javascript">
window.addEvent('domready', function() {

// Decorate the login windows to use a modal.
$ES('a.login').each(function(a){
a.setProperty('rel', '{size: {x: 175, y: 225}, ajaxOptions: {method: "get"}}');
if (a.getProperty('href').contains('?')) {
a.setProperty('href', a.getProperty('href')+'&tmpl=component');
} else {
a.setProperty('href', a.getProperty('href')+'?tmpl=component');
}
});

});
</script>

<p>
<a href="<?php echo JRoute::_('index.php?option=com_user&view=login'); ?>"
class="login" title="<?php echo JText::_('LOGIN') ?>">
<php echo JText::_('LOGIN') ?></a>
&bull;
<a href="<?php echo JRoute::_( 'index.php?option=com_user&task=register' ); ?>">
<?php echo JText::_('REGISTER'); ?></a>.
</p>

<?php endif; ?>

The display for the module when logged in is unchanged. But when not logged in only two links will be displayed: the login link and the register link. On the login link, a class of “login” has been applied. A small amount of unobtrusive Javascript has been used to add a modal popup on any anchor tags with a class of “login”. This technique degrades gracefully in the event that Javascript is disabled (so on a handheld device, clicking on the link will just take you to the normal login page).

Before we started, the login box will have looked something like the following image.

After creating the layout overrides, the display will change to something like the following image:

When you click the login link it will open the model popup login box. The description is still being displayed in the popup, so let’s look at taking that out (but still leaving it in if the full login page is displayed).

Open the login module layout override first (/html/com_user/login/default_login.php). Where the login description is being displayed, wrapped it in and if block to only display if it is being shown in a popup, as follows:

<?php if (JRequest::getVar('tmpl') != 'component') :? >
<div>
<?php echo $this->image; ?>
<?php if ( $this->params->get( 'description_login' ) ) : ?>
<?php echo $this->params->get( 'description_login_text' ); ?>
<br /><br />
<?php endif; ?>
</div>
<?php endif; ?>

The tmpl request variable is reserved in Joomla. If it has a value of “component” then we know that the outer site template is not being displayed (this happens in several places in Joomla, such as the “print” view in articles).

The final result will look something like the following image after we click on the “Login” link:

Those are the basic principles for creating an unobtrusive login box. You can download the layout overrides shown from joomlacode.org: popup_login_box_layout_overrides.zip. To install them, unzip the files into the /html/ folder in your default Joomla template. Remember to backup any files and folders that already exist (just in case).

Your valuable comments after reading this article will be highly appreciated. Also, if you have any issues in joomla you could email to harsha@vishmitha.com or Supporting Forum to get the assist.

The next article will discuss more about Layout Override in Joomla.

1183

Searching files in Linux

In our Linux basics series so far we have discussed a few areas ranging from the command line or GUI basics to basic administrative topics such as package management.

Modern Linux distributions tend to provide user friendly graphical interfaces comparable to anything available in other operating systems. For example if you consider the current or the upcoming releases of popular distributions like Ubuntu, Fedora, Mint and openSUSE, you will notice that they are very much in the same high quality GUI scale as Apple MacOS X or Microsoft Windows 7. In future articles we plan to discuss more and more graphical tools and tips as we move on. For today however we are planning to give you some tips about a command line tool which can impress your friends.

When you are working in a command line how would you locate a file or a directory? In a GUI you could browse the directories using a file browser or execute a search tool. Would you be surprised that you could search and locate files/directories in a Linux systems with ease using only command line tools, perhaps even better than GUI tools?

New Command: find

The command find is a traditional Unix command you would find in almost all Linux systems. Despite is simple name, the command is a very powerful tool. The price of that power is that the usage of find can be a little daunting for a new user. Perhaps in the past you have tried to use the command and failed or it didn’t give the intended output. Today we take control and learn a few things about find.

Find by the name

Let us have a look at the syntax of the basic find usage. It’s like:

The find has the ability to conduct searching based on many different criteria. For example let us search our home directory to find any files with the “.mkv” extension. If you remember the previous sessions, then you might recall that in Linux a file extension is just another part of the file name. So we are about to run a search based on the file name.

$ find where/to/look what-to-look-forThe find has the ability to conduct searching based on many different criteria. For example let us search our home directory to find any files with the “.mkv” extension. If you remember the previous sessions, then you might recall that in Linux a file extension is just another part of the file name. So we are about to run a search based on the file name.

Eg:
$ find ~ -name *.mkvLet us try to understand the above example in detail. First of course you know we are running the find command. The we give “~” as the location where to search for. Again if you recall previous sessions, “~” character refers to your home directory.

Then comes the curious part where we tell the find command the criteria of our search. By using “-name” option we tell it to base the search on the file name. As the name pattern we give “*.mkv” which means a name with any number of characters before the ending 4 characters which are “.mkv”.

Once significant thing to mention here is that our search patterns are case sensitive. Which means the above search will find a file named “Avatar.mkv” but not a file named “Avatar.MKV”. The reason is we are saying our search pattern is “*.mkv” not “*.MKV”.

What if we want to find the files with a certain pattern, regardless of the case (Upper, lower or mixed). In such a case (which is quite often) you have to use the option “-iname” instead of “-name”.

Now that you have a firm grasp of that, let try to find the same files inside your current directory.

Eg:
$ find . -iname *.mkv As you might have correctly remembered the “.” notation here is a shorten way of referring to the current directory. In the same sense you can use “..” instead of “.” to search in the parent directory of the current directory.

The where to look does not have to be one of those characters. For example we could tell find to search in the /tmp/play directory by

Eg:
$ find /tmp/play -iname *.mkv I case you were wondering, you can give multiple search paths as well in the find command.

Eg:
$ find . /tmp /usr/share/doc -iname *postgres*.pdfIn the above example we are telling find to search inside the current directory, “/tmp” and “/usr/share/doc” with the characters “postgres” in anywhere in the name and ending with “.pdf”.

As you can see, you can search anywhere in the file system where you have permission. This means that certain directories are not readable for regular users. In such as base you have to use find in conjunction with a command like “sudo” or “su -c” or else run it while logged in as the user “root”.

So far all the above examples are searching for a pattern in the file name. What if you want to search based on the file creation date, last accessed date or the file size.

At this point I am pretty sure that you won’t be surprised to know that “find” can do that too.

Find by the type

Now let us run a search to find only files. Which means directories matching the search pattern will not be included in the results. The option to search for the type is “-type”. So to search for files only we can give “-type f”.

Eg:
$ find . -type f -iname ubuntu*The above example will search the current directory for any files (no directories) with a name starting from the characters (case insensitive) “ubuntu”.

There are other different types that you can include in your search criteria. Simply use the relevant type character after the “-type” option.

f - regular file
d - directory
s - socket
l - symbolic link
If you don’t understand these types yet, that could because we have not talked about them yet. So no need to panic. If you somehow know them, then you can go ahead and give it a try.

Find by the time

Eg:
$ find . -type f -mtime 7 -iname *.odt The above example will search the current directory for any files (no directories) with a name ending with “.odt” which has been modified during the past 7 days. The “-mtime” option specifies the last modified time. If you need to use the last accessed time rather than the last modified time, then you can use the “-atime” option

Both “-atime” and “-mtime” takes the next parameter in days (i.e. 24 hours). So as in previous example “-mtime 7″ means last modified date is within 7 days (or 168 hours). What if you need to make these time based searched by minutes instead of days?

For those cases there are two similar options named “-amin” and “-mmin” which acts the same as “-atime/-mtime”, but only with minutes as in the following example.

Eg:
$ find . -type f -mmin 10 -iname *.odt

Find by the permissions

In the coming articles we can talk about the Linux security model with details including about the file permissions and ownership, etc. As for now it is enough to let you know that the find command has the ability to run searching based on file permissions too.

Eg:
$ find . -perm -o=wThe above example however asks find to look in the current directory for any file or directory where the “world/other” have write permission. If this does not make much sense to you, do not worry. We can discuss permissions later.

Find by the size

Another useful criteria when you are searching for things is the file size. In the real life application, a server configuration file or a word processed document should be much noticeably smaller in size than a video file of a full movie. As you can see when these kind of distinctions are possible, you can always use the “-size” option with parameters. Let us consider an example.

Eg:
$ find . -size 1024kThe above example will search the current directory for files with the exact size of 1024 kilobytes (i.e. 1 megabyte). Now what if we want to search all files larger than 1 gigabyte?

Eg:
$ find . -size +1GAs you can see in the above example we are asking find to look for anything larger than one gigabyte. What if we want to find something smaller than a particular size?

Eg:
$ find . -size -10M Yes, you guessed correctly. The above example will search for anything smaller in size than 10 megabytes. If you were wondering which are the character notation to specify the units we are going to use (Eg: megabyte, gigabyte, etc.), here are a few.

c - bytes
k - kilobytes
M - megabytes
G - gigabytes
Those four are not the only ones available, but those are the most commonly used ones as you can guess.

In the same lines you can easily search for empty files.

Eg:
$ find . -size 0c

Find by the owner

Apart from the above talked criteria, there is also the ability to run searches based on the owner of the file. Again the ownership and group ownership are two things we shall be discussing in a future article. For now you can assume that each and every file has an owner.

So to get back to the topic, we can ask find to search files/directories based on the ownership of a file by using the “-user” option with a user parameter.

Eg: $ find . -user gaveen

The above example will search the current directory for things owned by the user named “gaveen”.

Advanced: Perform operations based on the results

If you think the fun gets over there, you were wrong. Our friend “find” can also be utilized in many creative and advanced ways. However without straining you ming let us get to an example. Remember, it is just one of the things possible with find.

Eg:
$ find . -iname *.png -exec cp {} ~/test/ \;

Since the above example is more advanced than what we have already discussed, let us go through it carefully. First, part of the command might be familiar to you. Consider what is there from the beginning until the part “*.png”. As you might remember it is in fact searching for all files ending with the “*.png” inside the current directory.

Then there is this curious “-exec” option, which opens a whole new world of opportunities. Basically “-exec” executes some command we provide against the results of the first part of the find command. In this case we are asking to copy (using the cp command) the results of the first part of the find command into the directory located at “~/test”.

Let us examine the exec part more carefully. It says, execute cp with the destination location of “~/test”. The pair of curly braces acts as a place holder for the results from the first part of the command. So you must be catching this up gradually. But why the “\;” part?

When “-exec” runs a command, it runs the command for each single result. Which means if there are 25 results found by the first part, the cp command will run 25 times. Consider the “\;” as a break sequence which tells the “-exec” that the commands ends there. So the command completes by that sequence.

Hint: Common error message with find

One of the most common error message you would see with the find command is: “find: paths must precede expression”. This is annoying because after some rigorous rechecking of your command that you can be sure that it is correct. But it would not execute. For example if could be something like this.

Eg: $ find . *.rpm

The problem here is the shell getting confused by the “*” mark in the name pattern we entered. Here is the solution. Use “\” as an escape character for the “*”.

Eg: $ find . \*.rpm

It is good practice to escape special characters anyway in the Linux command line, even if it is not mandatory. In this case however it could be mandatory.

Congratulations if you have come this far. Now you know a fair amount about how to use find properly; one of the most underutilized commands in Linux/Unix which is also a very powerful command. Before we wrap up todays article let us combine some the options we discussed into an advanced find command.

Eg: $ find /tmp -type f -iname fedora*.iso -size +3G -mtime 300 -exec cp {} ~/test/ \;

What the above command is supposed to do is search for files (only) with a name starting with “fedora” and ending with “.iso” which are over 3GB in size and have a last modified date within 300 days, ans then copy them into the directory located at “~/test”.

Well, that is just about what we have to say about the find command today. You let me know if that last command is correct or not.

1216

Characters and their arrays

[You're Ted and you decide to learn some C++ from your friend Barney. This is the tenth day of the class]

You: Hi, Barney!

Barney: Hi, Ted! I was waiting for you.

You: I was a bit late, had some homework to do.

Barney: Oh, I know the kind of homework you do, he he. Anyway, where did we stop last time?

You: We discussed about arrays for two days.

Barney: Ah, yes. Then, enough of arrays. Now that you know how arrays operate, let’s talk about characters and their arrays, or strings, as we usually call them.

You: Okay.

Barney: So you know what a character is?

You: I think I do. It’s a single letter like ‘a’ or ‘b’, right?

Barney: Yes, not only letters, digits, punctuation marks like dots, commas, and special symbols, all of these belong to the set of characters. In fact the ASCII system has 256 characters in it.

You: Yeah, I’ve heard of that.

Barney: Good. We use the ‘char’ data type to identify characters in C++. Let’s see how they work from an example. Suppose you need to write a program where you need to do something and then prompt the user to ask whether he needs to do that again. If the user says yes, the process will be repeated. Let’s write a program that gives the two times of a given input.

You: He he, that’s a nice thing to program.

Barney: Just for the sake of exploring the use of ‘char’. First we ask the user to input an integer and we double it and print it in the screen. It’s as simple as this:

cout<<“Enter a number: “;
cin>>a;
count<<“Two times”<<a<<” is “<<(a*2)<<“\n”;

You: Okay.

Barney: Right, now the problem is how to ask the user to enter a value. We can use ‘cin’ for this. Also we can check his input using an ‘if’ condition. But we have to repeat the above code after that. How can we achieve that?

You: By using a loop, perhaps?

Barney: Exactly! We can use a while loop to do that. Let’s see how.

do{
cout<<“Do you want to continue [Y/N]? “;
cin>>c;
} while (c==‘y’ || c==‘Y’);

You: I see, it’s not that difficult. That ‘c’ should be declared as a ‘char’, right?

Barney: Of course. Let’s now complete the program:

#include<iostream>

using namespace std;

int main()
{

int a;
char c;
do{
cout<<“Enter a number: “;
cin>>a;
cout<<“Two times “<<a<<” is “<<(a*2)<<“\n”;

cout<<“Do you want to continue [Y/N]? “;
cin>>c;
} while (c==‘y’ || c==‘Y’);

return 0;

}

And let’s see if it works:

You: Hmm, works as expected.

Barney: Yes. That’s about chars. Now let’s talk about sequences of characters. We can define them using character arrays like this:

char name[]={‘d’,‘i’,‘g’,‘i’,‘t’,‘\0′};

You: But what’s that ‘\0’ thing at the end?

Barney: It’s called the null character. It signals that the character sequence ends there. Otherwise compiler doesn’t know where to stop. You’ll understand it more when we deal with pointers.

You: Okay.

Barney: For now, keep in mind that you have to add the null terminator when you declare character arrays like that. After assigning such an array we can print the whole word like this:

cout<<name;

You: I see. So you need not print character by character?

Barney: Of course not. But declaring strings in the above way is hard work. We can simplify this by using double quotes like this:

char name[]=“digit”;This one does the same job as our previous statement.

You: But what about the null character?

Barney: When you put double quotes, the null character is automatically appended. We call this adding the null character ‘implicitly’. In the former method we put it ‘explicitly’.

You: Okay.

Barney: Let’s see how to use such a character array in a program. Let’s write a program which asks the user to input his name and prints it back and mention the second letter in his name:

#include<iostream>

using namespace std;

int main()
{

char name[50];

cout<<“Enter your name: “;
cin>>name;
cout<<“Your name is “<<name<<” and the second letter in your name is”<<name[1]<<“\n”;

system(“pause”);

return 0;

}

You: But why name[50] instead of name[] ?

Barney: As in usual arrays, name[50] tells that the maximum number of characters we store in ‘name’ is 50. Of course it can be lesser than that, but not more.

You: I see. Shall we run it and see?

Barney: Go ahead.

Barney: He he, you know that name is banned in here these days.

You: Yeah, yeah, it’s the trending topic these days ne ;)

Barney: Alright then, that’s a brief introduction to character arrays. The next day we’ll talk about strings, and the string library functions C++ provides for us.

You: Okay, thanks. Bye Barney!

Barney: Bye, Ted!

1194

How to Edit Your CSS and HTML Files on Your Joomla Web Site

Your Joomla web site uses CSS to keep the text, background colours, module header colours, headings, etc the same throughout your site. If you want to change the colour of your content headings, your text, or background page colour, you would do this from the CSS file. You can also change the colours of your links, the background of your menus, or the name of image files that show up.

The HTML tells your template where to pull modules in, and includes the footer text on your template (depending on your template). If you want to change the footer text on your template, this is the place to do it. Also, some templates have some alternate options in the HTML file such as making your template right justified, centred, or left justified. Some also allow you to change whole colour schemes from the HTML file. Generally, this is found in templates you buy and the template will come with instructions on how to switch between the different options in the HTML file. It’s usually as easy as typing the name of the colour or entering a “1″ or “0″.The HTMLl file basically tells your Joomla web site template what to pull into view from the files on your server and where to display them.

 

How to edit your CSS file in your Joomla web site:

1) Log in to www.yoursitename.com/administrator

2) In the row of menus across the top, go to “Extensions”

3) Choose template manager in the drop down menus

4) Choose Site templates in the menu that slides out to the side

5) When the page loads, put a check mark in the box next to your default template.

6) Click “Edit” in the top right hand corner.

7) Change the parameters of your template you wish to change

8) Click “Edit CSS” in the top right hand corner.

9) Make changes to your CSS file that you wish to by select “template.css’’ and click Edit

10) Click the disk icon to save.

 

How to edit your HTML file in your Joomla web site:

1) Log in to www.yoursitename.com/administrator

2) In the row of menus across the top, go to “Extensions”

3) Choose template manager in the drop down menus

4) Choose Site templates in the menu that slides out to the side

5) When the page loads, put a check mark in the box next to your default template.

6) Click “Edit” in the top right hand corner.

7) Make changes to your HTML file that you wish to by clicking “Edit HTML” in the top right hand corner.

8) Click the disk icon to save.

 

Joomla’s hidden feature – hiding Intro Text

Joomla provides you with many options by which to display an article. However, did you know one of the most underutilised options is the fact that your article can hide its own “Intro Text”? The teaser you see in a blog layout, or a newsflash module, can be different when you actually display the full article.

Joomla Web sites typically use the “Intro Text” and the “Read more button” and just continue the story from the Front page Blog view, or a Newsflash module – but it doesn’t have to be that way. You can actually hide the Intro Text when displaying the full article.

To do this, edit the article in the Joomla Administrator.

Click on the “Parameters (Advanced)” pane to the right of the text of the article.

Find the parameter called “Intro Text” and change the select list to “Hide”. Your article might look something like the following screenshot.

(You will note that I’ve fixed up some of the typo’s since I took this shot.)

Save the article.

Now have a look at the article as it appears in a blog view, or a module, and then look at the full article.

We highly appreciate your valuable comments after reading this article. Also, if you have any issues in joomla you could email to harsha@vishmitha.com or Supporting Forum to get our assist. The next article will discuss about Layout Override in Joomla.

AI: Search Strategies for Problem Solving

After a small break in the AI article series, let’s move forward to understanding the next phase of problem solving through searching. Hope our readers can remember the article that appeared in diGIT’s February issue titled ‘Problem solving through Searching’. In that article, I presented the main ideas behind how problem solving in AI. There we went through steps required in problem solving, problem and solution formulation and some real world problems. In today’s article we would look at different ways in which searching can be used to solve problems. We would also look different search strategies available and discuss in detail about one such strategy.

 

Types of Search Strategies

Once we have formulated the problem (as discussed in February article), we have to decide how to find the solutions to those problems. This could be done by searching the state space. If you refer to the section titled ‘Defining Problems and Solution’ in the AI article in February issue, you would be able to refresh your memory about these terms.

When searching for a solution, you have start at the initial state of the search tree/graph and expand each state and visit connected states until the goal state has been reached. There are many ways to determine which state to expand in order to get to the goal state, which are known as ‘Search strategies’. These strategies can be mainly divided in to two groups known as ‘Uninformed search’ and ‘Informed search’ which are described in detail as follows.

  • 1. Uninformed Search – This is also known as ‘Blind Search’. This type of search means that they have no additional information about the states other than the information provided by the problem definition. This type of search can generate successor states and also make a distinction between a goal state and a non-goal state.
  • 2. Informed Search – This type of search strategy is more advanced than uninformed search. It is also known as ‘heuristic search’. This strategy has the ability to determine whether a non-goal state is much better than another non-goal state in arriving at the goal state effectively and efficiently, thus it uses heuristics based information on top of the information provided by the problem definition about the states in the state space.

In today’s article we will focus on uninformed search strategies and then move on to informed search strategies in the next article.

 

Uninformed Search Strategy

As explained above, in this type of search strategy we only have access to information given by the problem definition and there are no additional cues provided. One has to search the given state space expanding on each traversed state until the goal state has been reached. There are many different variations of how uninformed search can be achieved and some of those are explained as follows.

 

1. Breadth-first Search (BFS)

In this type of search, the main idea is that the root node is expanded first and then all the successor states of the root node are expanded afterwards. In the next step the rest of the successor states of the states traversed first would be explored. This activity is continued until the goal state for that specific problem is reached. So, at each state, it is checked whether it is the goal state or not. If we explain the breadth-first search in more specific terms, it requires all the nodes at a given depth of the search tree/graph to be expanded before going to the next depth level of the tree. Following search tree shows how breadth-first traversal works.

Figure 1 – Breadth-first traversal on the state space denoted by a search tree. The root node is ‘A’ and the goal node is ‘F’.

The breadth-first traversal searches the tree in this order as depicted by the red arrows.

 

A->B->C->D->E->F

It is also important to identify the pros and cons of BFS strategy.

Advantages:-

  • This uninformed search strategy can find the goal node where ever it is located in the search tree since it traverses the each node in a breadth-first manner until the goal node is reached. So we call this search strategy to be ‘Complete’ since it always guarantees that it finds the goal node at some level.
  • This finds the goal node is an optimal manner if each of the costs of traversing one node to the other is similar for the entire search tree.

Disadvantages:-

  • Consumes lot of time – For example if the goal node is located at a depth of say 1000 in the tree, it has to traverse all the nodes until the depth 1000 to reach at that goal node which would be computationally very expensive. So BFS is not suitable for complex and large problems with a high order search tree.
  • Consumes lot of space – At each node it expands the nodes connected to it in the next depth level. Therefore, at each iteration it has to keep in memory all the nodes that have visited so far leading to a high requirement of memory. Therefore we can conclude that BFS has a high time complexity and space complexity.

 

2. Uniform-cost Search (UCS)

As the name implies, this search strategy assumes that each of the path costs are equal. This is a simple extension to the BFS search algorithm that we discussed above on a special case when all of the path costs are equal. If the path costs are unequal, then this is exactly identical to BFS.

UCS expands the node with the lowest path cost at each iteration.

 

3. Depth-first Search (DFS)

In the depth-first search (DFS) strategy, there is a clear distinction from the BFS. This always expands the deepest node in the search tree and goes along the depth of each node rather than across the breadth. In figure 2, we have shown how DFS would work on the same search tree as used in illustrating the behavior of BFS.

Figure 2 – Depth-first traversal on the state space denoted by a search tree. The root node is ‘A’ and the goal node is ‘F’.

The depth-first traversal searches the tree in this order as depicted by the blue arrows.

 

A->B->E->F

In this particular scenario, it can be clearly seen that DFS find the goal node in less number of steps when compared to BFS (There can be situations where this would not hold as well).

Let’s now take a look at the advantages and disadvantages of the DFS search strategy.

Advantages:-

  • Better memory requirements – It only needs to store as single path from the root to leaf node, along the remaining unexpanded sibling nodes for each node in the path. Once a node has been traversed, it can be removed from the memory as soon as all its descendent nodes (immediate child and all other descendent nodes from that particular node – for example node B can be removed from memory once nodes E and F are traversed).

Disadvantages:-

  • Does not give an optimal solution – This search strategy might make a wrong choice in the earlier stages of the searching and keep on moving along a very deep path (or even an infinite path) for a long time never realizing that the goal node is not in that path because it does not have heuristics to understand that. Therefore, DFS does not give an optimal solution.
  • Does not give a complete solution – If there is a left sub-tree with no goal node, which spans in depth for a long path, DFS would keep on going down and down never terminating leading to an incomplete solution.

 

4. Depth-limited Search (DLS)

This is a small variation to the general DFS search explained above. Since the DFS search can lead to incomplete solutions due to depth unbounded trees (going down a path forever), depth-limited search ensures that the traversal along the depth of a path is limited to a certain pre-determined depth limit. For example, if we can assume that the goal node should be found within the depth limit of 5 from root node, in this case DLS would go down each path up to depth=5 only and search the tree until it finds the goal node eliminating the infinite-path problem found in general DFS search strategy. The problem with DLS is that it is hard to assume a best pre-determined depth-limit without affecting the solution. A way of finding the nest depth-limit is addressed below in no:5.

 

5. Iterative Deepening & DFS

This is another search strategy usually used as a combination with DFS which helps in finding the best depth-limit (which can be useful for applying depth-limited search). It starts off with depth=0 (only having the root node) and then gradually increasing the depth at each iteration until the goal node has been reached. This strategy tries to combine the good features of both BFS and DFS. As in DFS, its memory requirements are less and like BFS it is a complete algorithm given the branching factor from each node is a finite number and the path cost is a non-decreasing function of the depth of the node. This method is preferred for large search problems since it combines all the goodness of both BFS and DFS and tries to strike a balance between them allowing for better memory requirements and complete and optimal solution finding.

 

6. Bidirectional Search

Another type of uninformed search is called ‘bidirectional search’. As the name implies, it means running two simultaneous searches one starting from the root node (initial state) and the other starting from the goal node. In this case, the search starting from the initial state moves forward along the search tree while the other starting from the goal node moves backward until both the search runs meet at a single node in the middle.

 

Comparison between Uninformed Search Strategies

The following table shows a comparison between all the uninformed search strategies that we discussed throughout this article in terms of time and space complexities and also in terms of solution optimality and completeness. It would give you a clear idea as to how comparable each search strategy is to the others and also you can get the feeling that Iterative deepening and bidirectional search has goodness of all, although in practice they are hard to be implemented.

b – Branching factor of each node (how many branches are created from each node of the search tree) For example, if the search tree is a binary tree, then the branching factor of each node is equal to 2.

d – Depth of the shallowest solution (the depth of the place where the goal node is located form the root node)

m – Maximum depth of the search tree

l – Limited depth of the search tree used in depth-limited search

C* – Cost of the optimal solution (based on path cost)

E – Cost of every action

 

Next in Line

Today we looked different search strategies used in problem solving in AI. We focused on understanding various methods used in uninformed search strategies and discusses the pros and cons, features of each approach and they time and space complexities. In the next article, I would be explaining about the other main search strategy which is called the informed search based on additional heuristics.

References

Artificial Intelligence – A modern Approach, Second edition, Stuart Russell & Peter Norvig

1257

1. Introduction

A data structure is basically what it is. It is a structure of data. However, every data structure has a particular way of storing data, and data is retrieved / manipulated using certain operations which are defined for that data structure. The efficiency of these operations decide on the suitability of a data structure for a particular purpose.

 

2. Linked List

A linked list is a data structure which consists of a sequence of elements. Each element contains data and a link. The link is used to link with the next element in the record. The links are maintained with the use of pointers. The first element in the list is known as the head, and the pointer to the head is stored to perform operations on the linked list.

As we can see, the elements are linked together. The last link is a ‘Null’ pointer, signifying the end of the list. Since we only have the head pointer with us, we can not move to any random element in the list directly, we need to start from the head pointer and sequentially move to the next element, until we arrive at the desired element. This is known as traversing a list.

The most important operations on a Linked List are:

a) Insert: Insert an element in the beginning / middle / end of the list. Insertion at the beginning is O(1). If the pointer to the last element is stored, insertion at the end can be done in O(1). Since to insert in the middle, we would need to traverse the list, and if there are n elements in the list, the insertion is O(n).

b) Delete: Delete an element from the beginning / middle / end of the list. Deletion of elements have the same complexity as insertion.

 

Other types of Linked List:

a) Doubly Linked List:
A normal linked list has a link only to the next element. In a doubly linked list, each element has a link to the next and previous element.

This type of linked list allows traversal in both directions.

b) Circular Linked List:
In a circular linked list, the last element links to the head of the linked list. Thus, the next element after the last element, is actually the first one in the list.

struct node {
element e;
node *next;
};

node * head;

void insert_in_front(node * n) {
if(head == NULL)
{ head = n; head->next = NULL; return; }

n->next = head;
head = n;
}

void delete_in_front() {
if(head == NULL) {
cout << “Cannot delete”; return;

}
node * ret = head;
head = head->next;
free(ret); //If memory was allocated using malloc
}
element is a user-defined data-type. You can use templates to make it generic.

 

2. Stack

A stack is a data structure, in which elements are added to and removed from the ‘top’ of the stack. We can only access the element at the top of the stack. A stack can be maintained using a linked list with two restrictions as mentioned above, i.e. insertion and deletion happens only at the front of the list. A stack can also be implemented using an array.

 

The two operations involved in a stack are:

a) Push: Adding an element to the top of a stack is known as pushing an element. Pushing an element is an O(1) operation. If number of elements in a stack exceeds the desired limit, (or if it runs out of space if implemented using an array) it is known as a stack overflow error.

b) Pop: Removing an element to the top of a stack is known as popping an element. Popping the element is an O(1) operation. If an element cannot be popped, it is known as a stack underflow error.

c) Peek: This operation returns the element at the stack top. This is also an O(1) operation.

struct Stack {
int stack_top;
element stack[MAXSIZE]; };
void stack_init(Stack &s) {
s.stack_top = -1;
}
int stack_push(Stack &s, element e) {
if(s.stack_top == MAXSIZE) {
cout << “Stack Overflow”;
return -1;
}
s.stack[s.stack_top++] = e;
return 1;
}
int stack_pop(Stack &s, element &e) {
if(s.stack_top == -1) {
cout << “Stack Underflow”; return -1;
}
e = s.stack[s.stack_top--];
return 1;
}
int stack_peek(Stack &s, element &e) {
if(s.stack_top == -1) {
cout << “Empty stack”; return -1;
}
e = s.stack[s.stack_top];
return 1;
}

 

4. Tasks for you:
  1. Complete the code for Linked List to include insertion and deletion in middle and at rear.
  2. Extend the Linked List functions for Doubly Linked List and Circular Linked List.
  3. Study the Josephus’ problem and solve it using Circular Linked Lists.
  4. Using stacks, find the reverse of a string.
  5. A stack is used to check if parentheses are well-formed. For eg. “(())” and “()(())” are well-formed parentheses, but “((()” is not. Given a string, find if a string is a well-formed paretheses string using stacks.

1285

Designing a Website for Your Business

Up to last article of this series, we learned what is eMarketing and how can you strategize the eMarketing efforts for your business with the DEMO Model.

In this issue, I will talk about one of the fundamental requirements you should satisfy for being effective with eMarketing. That is to having a compelling website for your business.

Having a website for your business is a very fundamental requirement, before you go online with your business. The website is the base camp for your business, on the internet. You drive potential customers to the website, and then convince them to buy from you. What happen if your website fails to satisfy the visitors coming in search for a solution from your company? This is why it is very important for to have the website right from the outset, in order to get better results from your online marketing activities.

 

Who Owns the Website of Your Company?

A question so regularly asked and even more regularly answered incorrectly is “who should make the decisions about your company’s website?” A common trend in Sri Lanka is to passing the responsibility of the website to the most “techy guy” in the entire company (if it’s a small company), or to the Network/IT division if it is a larger company. The idea behind this is “website is a techy thing, and someone with an IT background should handle it”. A vast majority of websites fail to deliver sound business results, simply because of this blatant blunder committed by most well established companies in this country. On the other hand, most web design firms in Sri Lanka, started as freelance businesses by someone with the technical knowledge of setting up a website, or as joint ventures of few such people. These web design firms largely lacked the “business sense” when designing the structure of the website. Websites created by such firms for many clients in business sector, failed to deliver any tangible business results for the companies who used their services. This created a massive frustration among the business community in Sri Lanka, about the whole concept of having a website for their business. I have talked to many such Sri Lankan businessmen, who still believe having a website for their business is a mere waste of money; as a result of such bad experiences with low quality web design firms.

Web design firms alone cannot be blamed about this sad situation. Even the business community has done it wrong, when they first started setting up a website for their company. A friend of mine working for a well established web design company in Colombo told me, “90% of the time when we go for a client meeting, we are welcomed and hosted by the head of IT department and his team. Very rarely we are allowed to talk to the business and marketing people”. If you look at the websites of some of the biggest companies in Sri Lanka, you will see the information on those sites have not been updated for last 5 years. They simply followed the “trend” and put up a website, as yet another “IT department job”, and let it stagnating there forever. When they don’t see the expected “business results” from the website, they blame the internet as “a waste of time” and the web design people as “scammers”.

If you need business results from your website, let the business people handle the website. Your company’s website must be owned and managed by the marketing division, or (if you don’t have a marketing division) by the people who are most close to your customers. Every decision regarding the user interface of the website needs to be made by the marketing division. The role of IT is only to decide, what back-end systems to be used when creating the website. The rest; including the content, color theme, layouts, interface elements, are totally business decisions and must be made with the customer in forefront.

As I mentioned earlier, your website is a tool of communication with the customers. If it doesn’t integrate well with rest of your customer communications, or if it doesn’t contain the latest customer communications, then you will see your website is failing to communicate with the customers. When you run a new advertising campaign on TV, you should synchronize it with your website to reflect more relevant information about the new campaign. Because, your customers come online to search for more information on what you advertise. If you fail to give what they want; what you are doing is possibly turning back thousands of potential customers.

 

Importance of Usability

Usability; or the ease of navigating through the site to complete a desired action by a visitor is the most important factor you have to keep in mind when designing a website. It is known that up to 20% of all Internet users have some form of disability and 10% of males are colorblind. These factors need to be kept in mind when designing the interface of your website.

A website with poor usability is more likely to be abandoned quickly by its visitors. By improving some of the basic usability issues, a website can cut the bounce rate (percentage of visitors who view only a one page of the website) dramatically.

Before launching the website for your actual customers, you must test the site for usability among a sample of your target audience. If this is not possible, you should at least consult someone with both the knowledge of marketing and website usability to evaluate the site and make suggestions for improvements.

 

Selecting the Color Combinations

Research says that the visual appeal of a website is assessed within 50 milliseconds. Therefore it is really important to have an appealing look & feel for your website, for being convincing enough for your visitors. It should not look like a black & white document in Times New Roman font on an A4 sheet. On the other extreme, it should not look like the exterior of an up market Casino in Las Vegas. You should strike a balance in between these two extremes, and pick an ideal color scheme for your website.

The ideal color scheme should contain maximum 2 main colors, and a maximum of 5 to 6 variations of those two colors in total. Remember in mind that using as many as colors is not going to make your website appealing to the customers more.


Eg: The Facebook color theme contains a set of simple color variations.

The color scheme of your website should ideally match the corporate colors of your company, but it is not always a must. If you are choosing a different color platter, make sure you have at least one main color to resemble your corporate identity.

Once you select your color platter, then decide which exact color is to be used for different elements of your website like, for filling text boxes, colors of buttons, colors of headings, links etc. After deciding on these things, strictly adhere to the standards. For example, if you assign a particular lighter green for the buttons of your website; don’t use a blue color button in a deep linked page of your website. If you cannot decide alone the perfect color platter for your website, get the help from a professional designer or someone who is knowledgeable about colors and design elements.

 

How Search Engine Friendly is Your Site?

When designing your website, you must adhere to the basic guidelines of Search Engine Optimization (SEO), in order to be able to easily found by main search engines like Google and Yahoo. There are number of “on site factors” that you have to keep in mind when designing your website. You must have a basic knowledge in Search Engine Optimization, or you should consult someone with the skill of SEO, before you make a final decision of your website’s design. These basic factors that you have to pay attention includes (but not limit to) the factors such as..

  • Validating your HTML code so it is “spider” compliant
  • Making sure you use the correct file names (URLs) for your web pages (Dynamic Vs Static pages)
    The Title Tag should be compelling and focused
  • Your description tag needs to work hand-in-hand with the title to get the searcher to “click” on the listing.
  • Every page should have a unique title & description
  • JavaScript should be referenced as an external file
  • CSS should be referenced as an external file
  • Main graphics uare tagged with proper ALT tags

 

Conversion Funnel

A business website should have a business objective in focus, even if the objective is not an eCommerce conversion. It might be a sales lead for your offline business, or sign up to your newsletter. You should have a clear picture in mind, how your visitors will navigate through to the objective of your website. This expected navigation path towards the ultimate goal, is known as the “conversion funnel” of your website. When designing the website, you should make sure the content on your website does not disturb this expected conversion funnel, and at the same time you have to make sure your site contains enough resources and tools for the user to navigate easily through to the ultimate goal. Failing to have the supporting content and tools may result in the visitor abandoning your site at some point, before completing the goal.

 

Summary

We learned that, the design of the website can either make your business or break your business, depending on the effort you put towards planning your website. We further learned that the website of a business firm, should always be managed by the marketing department, and not by the IT department. When designing a website, you must focus on its usability, color theme, ease of navigation, the search engine friendliness, and the conversion funnel towards the business goal.

 

In the Next Issue

Up to now, in the four articles so far in this series, what we have discussed is mainly about how to strategizing your emarketing efforts. Now with the strategy is properly in place, from next issue onwards we will focus on the execution part of your eMarketing strategy. In the next issue, I will cover the Search Engine Marketing in general, and later on I will take each of the Search Engine Marketing tools in details.

1188

Yum and APT

In the last issue we discussed some basic concepts behind package management in Linux. It is probably good to remind again that in moder Linux distributions installing/uninstalling software is handled via a package management tool. It might not be a very familiar concept to people from different backgrounds such as Windows and MacOS. However Linux users must be quite familiar with how managing packages are done.

The main plus point is you can get all the software you need using one method and having the ease of updating the system, and also keep receiving updates automatically. Once you wrap your head around the basics you will noticed that Linux is one of the easiest environments to install, manage and remove software. Package management itself is one of the features that sets Linux apart from the rest od the mainstream operating systems.

If you have not heard already, there are several package management system approaches in the Linux world. Here are some of the commonly found ones.

 

  • RPM/Yum – Used by Fedora, Red Hat Enterprise Linux, CentOS, openSUSE, SuSE Linux Enterprise Server, Mandriva, etc.
  • DPKG/APT – Used by Debian, Ubuntu, Mint, etc.
  • Portage – Used by Gentoo

There are many other tools available in the form of TGZ format files in Slackware distribution and so on. However RPM and DPKG based systems are notable very popular. Each of these systems may use a different set of tools for operations.

 

Relationship between packages, formats, tools and systems

We discussed what a package management system is, in the last issue. So you should have a fair idea about what to expect. In an extension to that we already discussed what is the relationship between a package management system and its tools. In short package management tools are the software tools we use to execute operations in a package management system. A package format is the anatomy or the composition of a package archive, while a package itself is a single archive of that particular format.

In example RPM based package management systems uses software packages of the RPM format and use tools such as “yum” command to execute operations such as add remove software.

Today we are going to look into the two most popular package management tools: Yum and APT.

 

RPM and Yum

RPM stands for RPM Package Manager (used to be Red Hat Package Manager). It was started by Red Hat but later became the package management infrastructure of choice for many Linux distributions including Fedora, RHEL, CentOS, openSUSE, SLES, Mantriva and more. Another notable fact about RPM is that it is the package format used in the Linux Standard Base, a standard for Linux distributions maintained by the Linux Foundation. If you do not know about the Linux Foundation, it is the primary non-profit consortium chartered to foster the growth of Linux which is also the employer of Linus Torvalds (creator and maintainer of Linux).

The native package format used in RPM is also named RPM packages usually with the extension “.rpm”. For example a released RPM package for the software called “checkinstall” could be “checkinstall-1.6.1-1.i386.rpm”. In our simple example we can notice that the software package in question is named “checkinstall” and is in the version 1.6.1-1 for the i386 (x86) hardware architecture.

RPM package format was developed earlier to be used in discreet package releases. Which means each and every new release would be a completely new full package. However recently the concept of package-deltas in the form of delta-rpms were added into this systems. This enables the RPM system to fetch only the changed portions of the software when a new version is released.

The command line utility to execute operations within the RPM system is named “rpm”. Let us now see a few RPM related commands.

To install a downloaded new package (located in the working directory) named “somepackage” with the version number 1.0.0 and hardware architecture neutral:
# rpm -ivh somepackage-1.0.0-1.noarch.rpm

To upgrade the “somepackage” from an older verion to the new version:
# rpm -Uvh somepackage-1.1.0-1.noarch.rpm

To freshen the package “somepackage”. Works only if “somepackage” is already installed
# rpm -F somepackage-1.1.2-1.noarch.rpm

To uninstall the package “somepackage”:
# rpm -e somepackage

To query which packages with a name starting with “some” are installed
# rpm -qa some*

To query the files installed by the package “somepackage”
# rpm -q somepackage --filesbypkg

To query which package incuded the file /etc/nanorc
# rpm -q -f /etc/nanorc

The RPM system was designed to handle only one version of a given software in a given system. This behavior complies with most of other package management systems available for Linux.

Even though RPM identifies missing dependencies for a package, RPM itself does not provide an easy means of solving dependency related issues. This and several other new features combined gave different vendors the idea to build high-level tools based upon RPM. For example tools like “yum” and “urpmi” came into being.

Yum started it’s life as YUM, the Yellow Dog Updater Modified as a part of the Yellow Dog Linux distribution. It was since been adopted by Red Hat as the preferred high level tool for package management providing additional features on top of RPM. For example it provides an easy means of handling dependencies by incorporating the concept of package repositories.

 

New Concept: Package Repository

A package repository is a location where a collection of software packages are stored for easy retrieval. For example most Linux package management systems use repositories to provide much needed software compilations where you can select and install. For example a 3rd party repository called RPMFusion (located at rpmfusion.org) is very popular among Fedora Linux users. Meanwhile the Fefora project hosts their official repositories too.

These package repositories can be added or removed from a system with ease. Fedora, RHEL and similar stores Yum package repositories related information inside the directory: “/etc/yum.repos.d/” directory while Debian/Ubuntu systems store APT repository information in “/etc/apt/sources.list” file.

So let us try a few Yum commands.

To search if there is a package with the pattern “vpn” in its name or the description
# yum search vpn

To list the details of the package “openvpn”
# yum list openvpn

To install the package “openvpn”
# yum install openvpn

To update the package “openvpn” into the latest version available
# yum update openvpn

To remove (uninstall) the package “openvpn”
# yum remove openvpn

To search for the names of package groups starting with “gn”
# yum grouplist gn*

To install the package group “GNOME Software Development”
# yum groupinstall "GNOME Software Development"

To downgrade the version of the package “leafpad” from the current version to the previous highest version
# yum downgrade leafpad

To see the summery of the past Yum transactions
# yum history

Further, Yum has this advanced mode called the yum shell. Yum shell is an interactive environment where you can run Yum based commands in succession. Once you have completed your commands you have to option to commit the changes you made. Yum will then take your operation and execute all in one single transaction. This feature alone can make a big difference in tricky situations.

Yum Shell can be invoked by running
# yum shell

As you can see clearly Yum/RPM provides a powerful package management infrastructure. It is also worthy of mentioning that RPM is the preferred format in the upcoming MeeGo distribution for Linux based hardware device (Eg: mobile phones, tablet PCs, media players, e book readers, etc.) sponsored by Intel and Nokia.

 

DPKG and APT

While RPM was available for Red Hat Linux in the 90s, Debian project had their own package management going. Their package format was called a Deb package which usually had the extension “.deb”. The command used for the operations was called “dpkg”. Here’s a few “dpkg” commands.

To install a downloaded new package (located in the working directory) named “somepackage” with the version number 1.0.0 and hardware architecture of i386:
# dpkg -i somepackage-1.0.0.i386.deb

To uninstall the package “somepackage”:
# dpkg -r somepackage

To query which packages with a name starting with “some” are installed
# dpkg-query -l some*

To query the files installed by the package “somepackage”
# dpkg -L somepackage

To query which package incuded the file /etc/nanorc
# dpkg -S /etc/nanorc

Even though the development of decent high end tools for RPM was fairly new, Debian had the upper hand there. They had APT, which stands for Advanced Package Tool for quite some time before Yum came into being. Naturally APT was better geared than “dpkg” to handle dependencies.

So let us now try a few APT based commands:

To search if there is a package with the pattern “vpn” in its name or the description
# apt-cache search vpn

To list the details of the package “openvpn”
# apt-cache search openvpn

To install the package “openvpn”
# apt-get install openvpn

To remove (uninstall) the package “openvpn”
# apt-get remove openvpn

As you can see APT also provides a feature set complete with advanced options. The choice of package management tools between APT and Yum are thus, largely a personal choice. It is however very incorrect to compare “apt-get” to “rpm” or, “yum” to “dpkg”. The low-level commands for each platform are “rpm” and “dpkg” while the high-level tools are “yum” and “apt-*” respectively.

Additionally there is a tool called “apt-rpm” which enables the use of APT system on RPM based distributions (Eg: Fedora, RHEL/CentOS). New generation tools like Smart Package Manager and PackageKit has the ability to use more than one package management toolset in a single system.

 

Graphical Frontends

Other than the command line tools, both of the above systems sport several GUI tools as frontends to their respective package management systems. Let us now take a brief look at two of them.

Recent versions of the Fedora distribution ship with a GUI application named “gpk-application” (mainly for GNOME Desktop Environment). It is a better replacement to the GUI tools previously available. The “gpk-application” also relies on the Yum/RPM and PackageKit integration in Fedora. It has the ability to search for packages, mark packages for install/uninstall operations, search and install package groups among other features. This tool is likely to appear in future versions of RHEL and CentOS too.


Image 1: gpk-application
On Debian/Ubuntu systems, again (mainly for GNOME Desktop Environment) there is the Synaptic Package Manager working as a frontend for DPKG/APT. It also has the ability to search for packages, mark packages for install/uninstall operations, among other things. One nice feature is the ability to generate a list of packages for future use or a script for separate downloading. It is also available under Ubuntu and Mint.


Image 2: Synaptic Package Manager