Bits of Learning

Learning sometimes happens in big jumps, but mostly in little tiny steps. I share my baby steps of learning here, mostly on topics around programming, programming languages, software engineering, and computing in general. But occasionally, even on other disciplines of engineering or even science. I mostly learn through examples and doing. And this place is a logbook of my experiences in learning something. You may find several things interesting here: little cute snippets of (hopefully useful) code, a bit of backing theory, and a lot of gyan on how learning can be so much fun.

Friday, November 30, 2007

Operator overloading

Don't overload the ostream & operator <<. Reason: You can't have this operator as a member function of a class (let me know if I am wrong). Therefore, there doesn't seem to be a way for using polymorphism by declaring these operators as virtual.

#include
#include
#include

using namespace std;

class some
{
protected:
string id;
public:
some (string aid){ id = aid; }
friend ostream & operator (ostream &, some &);
};

ostream & operator << (ostream & fout, some & asome)
{ fout <<
"Class some: " << id << endl;}


class someother : public some
{
public:
someother (string aid) : some (aid){}
friend ostream & operator << (ostream &, someother &);
};

ostream & operator << (ostream & fout, someother & asome)
{ fout <<
"Class someother: " << id << endl;}

int main ()
{
some A ("A");
some
B ("B");
some * C = new
someother ("C");
cout << style="color: rgb(0, 0, 0);">;
cout << B;
cout << (*C);
delete C;
return 0;
}

output:


Class some: A
Class some: B
Class some: C



As you can see above, the objective was to call the operator <<



#include
#include
#include
using namespace std;



class some
{
protected:
string id;
public:
some (string aid){ id = aid; }
friend ostream & operator << (ostream &, some &); virtual ostream &
print (ostream & fout)
{
fout
"Class some: " <<>return fout;
}
};


class someother : public some
{
public:
someother (string aid) : some (aid){}

virtual ostream &
print (ostream & fout)
{
fout <<
"Class someother: " <<>return fout;
}
};


int main ()
{
some
A ("A");
some
B ("B");
some * C = new
someother ("C");
A.
print (cout);
B.
print (cout);
(*C)
print (cout);
delete C;
return
0;
}

Thursday, August 23, 2007

Classes versus Functions

While working with an OO language like C++ or Java, we often stumble into an issue of choosing between a class and a function.

Let me illustrate the case. Say, we are writing a parser. A C-style way to do is to form it in the shape of a function, say parse (FILE * fin) , that returns the IR after parsing. The caller of this function would be responsible to do what he wants with the IR.

There are more one choice to do the same thing when working with an OO language. A class named Parser would possibly have a parse (FILE * fin) method returning the IR. Or it could have a constructor Parser (string FileName), and an argument-less method parse () returning the IR. The merits of choosing one over the other seem to me rather unimposing. The only difference between the two approaches is that the input for parsing is defined while making a call to the method in the former case, while, in the latter, it gets defined at the time of the creation of the parser object. It hardly matters!

For me, in a basic case, having a parser class is little more than syntactic sugar. May be, in a more advanced scenario, it helps having a class for the Parser, so that parser states can be encapsulated in private attributes. Among these, FileName is surely not one. It can always be passed to the parse method while calling.

I arbitrarily prefer having a parameterised method parse (FILE * File) or parse (string FileName), so that I can use the same parser object for parsing many times. Nothing fundamental about this choice.

Thursday, June 28, 2007

A Software Engineering Practice Problem

Suppose team A has built a module M, which is used by many of the products of A. Team B borrows M from A. While using it, they find a bug in M. In that process, they also create a fix which works for them. The question is: What should be the process by which the bug is reported to team A, and how should the fix be incorporated?

The potential difficulty is that there are many products that A had made which use M. Hence, if the fix is incorporated in the next version, all those products need to be regression tested.

Of course, it's a very common problem, and people must be doing something to solve it at their own level. Can we note down some common-sense technique here?

Friday, March 16, 2007

A Small Test Automation System

Here I describe a small test automation system that has come in handy for me. It's very crude and would obviously work for very small scale individual level software development. The kind of software it would work for are those which take an input in the form of a file or from standard input, and output it into the standard output. In particular language translators. However, I am sure that it covers a very broad ground. And a simple constraint of having to build your translator, so it is testable by this kind of testing system will automatically result in good programming practice. I can guarantee that it has yielded some bit of productivity rise for me, a significant increase in correctness as testing and bug catching was easier and hence done more freely, exhaustively and frequently, and hell lot of fun!

We create a directory named test in the directory where the program executable (let's call it prog) is placed. In this directory we create the following directories:
* input : The directory which contains all the inputs of the test cases
* output : The directory where the test harness will dump the outputs of running the prog on each test into a separate file of the same name (possibly with file name extension .out)
* expect : The directory where the expected output of each test case is placed in a separate file of the same name
(possibly with file name extension .exp)
* description : The directory where the description of each test case is placed in a separate file of the same name (possibly with file name extension .desc)

We work with the following scripts (written in your favourite scripting language). They are the following:
- createtest : This script asks for a test case name and creates the same. It will look for the input file of the same in the input directory, and will run the prog on it, dumping the output into a file of the same name in the expect directory after getting the user's consent about the correctness of the generated output.
- testTestCase : This script takes as an input a test case name, runs prog on the corresponding input file in input directory, and dumps the output into the output directory. Then it does a simple unix diff between the expected output (the file of the same name in the expect directory), and generated output (the file of the same name in the output directory). It plants the PASS or FAIL verdict into a file (with .log extension) into the current working directory.
- testTestSuite : This script takes as an input the name of a test suite file. The test suite file should contain the names of all the test cases to be tested in the test suite. The testTestSuite runs similar to testTestCase script on all the test cases. It plants its PASS or FAIL verdict for each test case into a file of the same name as the test suite.



createTest.sh
#/bin/sh

inputdir="./${1}/input/";
outputdir="./${1}/output/";
expectdir="./${1}/expect/";
descriptiondir="./${1}/description/";

if [ $# -ne 2 ]
then
echo "Usage - $0 app-name test-case"
exit 1
fi

testcasename=$2

ls ${descriptiondir}${testcasename}.desc
if [ "$?" = "0" ]
then
echo "Current Description: `cat ${descriptiondir}${testcasename}.desc`"
echo "Do you want to change the description? (y / n)"
read isNewDesc
if [ "$isNewDesc" = "y" ]
then
`rm ${descriptiondir}${testcasename}.desc`
grep "\/\/" ${inputdir}${testcasename}.kc >> ${descriptiondir}${testcasename}.desc
fi
else
grep "\/\/" ${inputdir}${testcasename}.kc >> ${descriptiondir}${testcasename}.desc
fi

ls ${inputdir}${testcasename}.kc
if [ "$?" = "0" ]
then
echo "Current Input: `cat ${inputdir}${testcasename}.kc`"
echo "do you want to change the input? (y / n)"
read isNewInput
if [ "$isNewInput" = "y" ]
then
`rm ${inputdir}${testcasename}.kc`
unset f
echo "type the test input data (to end the input, type 'eof' in the line following the last input line):"
while :
do
read f
if [ "$f" == eof ]
then
echo "Input data done"
break
fi
echo $f >> ${inputdir}${testcasename}.kc
done
fi
else
unset f
echo "type the test input data (to end the input, type 'eof' in the line following the last input line):"
while :
do
read f
if [ "$f" == eof ]
then
echo "Input data done"
break
fi
echo $f >> ${inputdir}${testcasename}.kc
done
fi

cat ${inputdir}${testcasename}.kc | ../${1} > ${expecteddir}${testcasename}.exp

./viewtest.sh $1 $testcasenam

testTestCase.sh
#/bin/sh

if [ $# -ne 2 ]
then
echo "Usage - $0 app-name test-case"
exit 1
fi

inputdir="./${1}/input/";
outputdir="./${1}/output/";
expectdir="./${1}/expect/";

CurrentIn="${inputdir}${1}.kc"
CurrentOut="${outputdir}${1}.out"
echo $CurrentIn
echo $CurrentOut

cat $CurrentIn | ../${1} > $CurrentOut

echo "Test result for application ${1} test-case ${2}"
CurrentExpected="${expectdir}${2}.exp"
CurrentOut="${outputdir}${2}.out"
echo "Comparing $CurrentExpected and $CurrentOut"
diff $CurrentExpected $CurrentOut > ${1}.${2}.log
if [ "$?" != "0" ]
then
echo "Test case $2: FAILED!"
else
echo "Test case $2: PASSED!"
fi


testTestSuite.sh

#/bin/sh

if [ $# -ne 2 ]
then
echo "Usage - $0 app-name test-suite"
exit 1
fi

inputdir="./${1}/input/";
outputdir="./${1}/output/";
expectdir="./${1}/expect/";

echo "testing application ${1} on test-suite ${2}"
while read f
do
CurrentIn="${inputdir}${f}.kc"
CurrentOut="${outputdir}${f}.out"
echo $CurrentIn
echo $CurrentOut
cat $CurrentIn | ../${1} > $CurrentOut
done < $2

if [ `ls ${2}.log` ]
then
rm ${2}.log
fi

echo "Test result for test-suite ${f}"
while read f
do
CurrentExpected="${expectdir}${f}.exp"
CurrentOut="${outputdir}${f}.out"
echo "Comparing $CurrentExpected and $CurrentOut"
diff $CurrentExpected $CurrentOut > temp
if [ "$?" != "0" ]
then
echo "Test case $f: FAILED!" >> ${1}/${2}.log
else
echo "Test case $f: PASSED!" >> ${1}/${2}.log
fi
done < $2
rm temp



A test suite
1
2
3
4
5
6
7
8
9
10
11
12
19
20
21
22
23
24
25
26

A test verdict:
Test case 1: PASSED!
Test case 2: PASSED!
Test case 3: PASSED!
Test case 4: PASSED!
Test case 5: PASSED!
Test case 6: PASSED!
Test case 7: PASSED!
Test case 8: PASSED!
Test case 9: PASSED!
Test case 10: PASSED!
Test case 11: PASSED!
Test case 12: PASSED!
Test case 19: PASSED!
Test case 20: PASSED!
Test case 21: FAILED!
Test case 22: FAILED!
Test case 23: FAILED!
Test case 24: FAILED!
Test case 25: FAILED!
Test case 26: PASSED!

A download page for this tool (with a more up to date source code and instructions for use)

Friday, February 23, 2007

Changing screen resolution

For a linux machine, the screen resolution can be changed by setting it in the following file:
/etc/X11/xorg.conf

In the section named 'Screens' add a 'Display' subsection. Something like:
Subsection "Display"
Depth 24
Virtual 1280 800
EndSubsection

It sets the screen resolution to 1280 x 800.

Tuesday, February 06, 2007

Automation for IISc

Have you ever felt frustrated to find the bathroom lamp broken and having to go all the way to the complaint cell to lodge a complaint? It's not the going which is the painful part, rather the remembering-to-go part which is painful. How nice would it be to be able to lodge the complaint right at the moment you notice or remember it? A bit of automation would definitely help, wouldn't it? If, just by clicking on a link, you could lodge your complaint and track its progress, it would bring in so much more sanity in our life. Another example: Booking the guest rooms and tracking the vacancies online etc etc. That would save us the trouble of waiting at the Hostel office at 4 PM a month before the occupation date (and then possibly getting disappointed).

I intend to maintain a list of ideas for automation that can be done in the day to day working in IISc. The idea can be picked up by the administrators for implementation. This is a very humble effort. The more difficult part -- that of implementing and deploying and getting them accepted by the IISc system -- remains by far the tougher part of the job. I consider it a viable idea to create proof-of-concept prototypes in the Software-Architecture course term-projects by CSA students. The analysis and design, and possibly the source-code, can then be reused to implement the deployed system. I think getting them implemented by professional software developers is very much a possibility. It shouldn't be unaffordable.

Foreseeable Problem
An obvious hurdle in getting this working is that of coupling this with a centralised database of IIScians. That system has to be 24 X 7 available, up-to-date, consistent and secure. While setting up of such a database would require some work, the development of the above systems can be done in parallel with some foresight.

Visitors to this post may contribute by:

  • Suggesting additional such problems
  • Providing links to already existing resources which can be reused
  • Providing the solutions themselves, partial or complete
  • Pointing out possible problems in implementation of these systems. The problems would preferably be technical, or at least apolitical.
Online Complaint Cell
It should be possible to place civil and electrical complaints online by all members of the campus. The system should allow tracking of the complaints.

Online Guest Room Booking
Making the process of guest-room booking online will make the process fast, trouble-free and transparent. It should be possible see the accommodation status of various guest-houses in the campus online.
(Think of the Railway, Airline, Hotel ticket booking systems we use so often).

Online Course Registration
Instructors may float their course on the department web page with a provision for students to apply for registration. The instructor may then go through the details of the student and decide to pass or reject the application. Depending on the availability of course/participants, the complete thing can be automatically scheduled (I had implemented a program that modelled this part as a graph-colouring problem to create a schedule, unless unschedulable).

Automated Web-Page Creation
It's so much easier to reach out to the world if you have your own official webpage. Being in IISc, and having to create webpages in geocities and googlepages is a lot less cool. Can't we have an equally convenient system which allows creation of our webpages in our departmental servers? The creation and editing should be easy with a couple of clicks of buttons.
(think of orkut, geocities, blogspot etc. which allow creation of whacky webpages with a few clicks of buttons.)

Research Publications Page
We could have a portal that gives an interface to manage our publications page. It allows us to add/modify/delete entries, organise them in different categories (conference, journal etc.). This could be a part of the automated web-page creation portal.


IISc Blog (eVoices)
I see it as some kind of an idealised 'Voices' where IIScians blog freely. The featured blogs can then be published in a hard-copy version of Voices.
(We had implemented a primitive version of this long time back, but it needed a lot more work to scale up).