Re: Refactor/Rewrite Perl code in Python

2011-07-25 Thread Shashwat Anand
Thanks everyone for the insight.
I got the idea as to how and where to start.
Guess I need to work in Perl for now, so as to start the conversion process.
Regarding Tests, I had already started writing tests before posting.
Writing tests for every module will be a pain as well as a nice experience.

Thanks.
~Shashwat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Refactor/Rewrite Perl code in Python

2011-07-25 Thread J Kenneth King
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes:

 On Sun, Jul 24, 2011 at 7:29 PM, Shashwat Anand anand.shash...@gmail.com
 wrote:

 How do I start ?
 The idea is to rewrite module by module.
 But how to make sure code doesn't break ?

 By testing it.

 Read up on test driven development.

 At this point, you have this:

 Perl modules: A, B, C, D
 Python modules: none
 Python tests: none

 Now, before you rewrite each Perl module in Python, first write a good,
 comprehension test suite in Python for that module. You need to have tests
 for each function and method. Test that they do the right thing for both
 good data and bad data. If you have functional requirements for the Perl
 modules, use that as your reference, otherwise use the Perl code as the
 reference.

 For example, this might be a basic test suite for the len() built-in
 function:


 for empty in ([], {}, (), set([]), ):
 if len(empty) != 0:
 raise AssertionError('empty object gives non-zero len')

 for n in range(1, 5):
 if len(x*n) != n:
 raise AssertionError('failure for string')
 for kind in (list, tuple, set):
 obj = kind([None]*n)
 if len(obj) != n:
 raise AssertionError('failure for %s' % obj)

 if len({'a': 1, 'b': None, 42: 'spam'}) != 3:
 raise AssertionError('failure for dict')

 for bad_obj in (23, None, object(), 165.0, True):
 try:
 len(bad_obj)
 except TypeError:
 # Test passes!
 pass
 else:
 # No exception means len() fails!
 raise AssertionError('failed test')



 Multiply that by *every* function and method in the module, and you have a
 moderately good test suite for module A.

 (You may want to learn about the unittest module, which will help.)

 Now you have:

 Perl modules: A, B, C, D
 Python modules: none
 Python tests: test_A

 Now re-write the Python module, and test it against the test suite. If it
 fails, fix the failures. Repeat until it passes, and you have:

 Perl modules: A, B, C, D
 Python modules: A
 Python tests: test_A

 Now you can be confident that Python A does everything that Perl A does.
 Possibly *better* than the Perl module, since if you don't have a test
 suite for it, it probably has many hidden bugs.

 Continue in this way with the rest of the modules. At the end, you will have
 a full test suite against the entire collection of modules.

A very sane approach.

I currently support a large legacy application written in C++ by
extending it with Python.  We managed to do this by wrapping the legacy
application with a Python interface using the Boost::Python libraries.
It has allowed us to embrace and extend the legacy code and replace bits
of it one piece at a time while keeping the whole application running.

Now I am not aware of any Python bindings to the Perl interpreter, but
if there is some FFI library that makes it possible this approach might
be viable for your project.

The trade-off of this approach is the extra complexity of maintaining
another interface in your code.  The beneift is that you can avoid
re-writing a large amount of code up front.  This works particularly
well when the legacy system has a rather large user base and you don't
have a robust test suite for the legacy code.

One book I found particularly useful: 

http://www.amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052

hth
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Refactor/Rewrite Perl code in Python

2011-07-25 Thread Sells, Fred
Sometimes it's worth asking Why?

I assume there would be no need to rewrite if the existing code did most
of what was needed.  It may be easier to ask the customer what he really
wants rather than to re-engineer a crappy solution to an obsolete
problem.

-- 
http://mail.python.org/mailman/listinfo/python-list


Refactor/Rewrite Perl code in Python

2011-07-24 Thread Shashwat Anand
I am working with a huge codebase of Perl.
The code have zero documentation and zero unit-tests.
It seems like a huge hack.

The underlying database schema is horrid.
So I want to rewrite the whole of it in Python.

How do I start ?
The idea is to rewrite module by module.
But how to make sure code doesn't break ?
How can I import perl and python codes in each other ?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Refactor/Rewrite Perl code in Python

2011-07-24 Thread Chris Angelico
On Sun, Jul 24, 2011 at 7:29 PM, Shashwat Anand
anand.shash...@gmail.com wrote:
 How do I start ?
 The idea is to rewrite module by module.
 But how to make sure code doesn't break ?
 How can I import perl and python codes in each other ?

Can you separate the project into separate executables that call on
each other? You can pipe text from stdout of perl to stdin of python,
for instance. Otherwise, it's not going to be easy. But if you're
going to change the underlying database AND the code at the same time,
it may be best to simply set aside the old code completely and code a
brand new system in Python, capitalizing on the Second Mouse Effect
(the early bird gets the worm, but the second mouse gets the cheese).
You can learn from all the mistakes made in the first version,
allowing you to make an entirely new set of mistakes. :)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Refactor/Rewrite Perl code in Python

2011-07-24 Thread Steven D'Aprano
On Sun, Jul 24, 2011 at 7:29 PM, Shashwat Anand anand.shash...@gmail.com
wrote:

 How do I start ?
 The idea is to rewrite module by module.
 But how to make sure code doesn't break ?

By testing it.

Read up on test driven development.

At this point, you have this:

Perl modules: A, B, C, D
Python modules: none
Python tests: none

Now, before you rewrite each Perl module in Python, first write a good,
comprehension test suite in Python for that module. You need to have tests
for each function and method. Test that they do the right thing for both
good data and bad data. If you have functional requirements for the Perl
modules, use that as your reference, otherwise use the Perl code as the
reference.

For example, this might be a basic test suite for the len() built-in
function:


for empty in ([], {}, (), set([]), ):
if len(empty) != 0:
raise AssertionError('empty object gives non-zero len')

for n in range(1, 5):
if len(x*n) != n:
raise AssertionError('failure for string')
for kind in (list, tuple, set):
obj = kind([None]*n)
if len(obj) != n:
raise AssertionError('failure for %s' % obj)

if len({'a': 1, 'b': None, 42: 'spam'}) != 3:
raise AssertionError('failure for dict')

for bad_obj in (23, None, object(), 165.0, True):
try:
len(bad_obj)
except TypeError:
# Test passes!
pass
else:
# No exception means len() fails!
raise AssertionError('failed test')



Multiply that by *every* function and method in the module, and you have a
moderately good test suite for module A.

(You may want to learn about the unittest module, which will help.)

Now you have:

Perl modules: A, B, C, D
Python modules: none
Python tests: test_A

Now re-write the Python module, and test it against the test suite. If it
fails, fix the failures. Repeat until it passes, and you have:

Perl modules: A, B, C, D
Python modules: A
Python tests: test_A

Now you can be confident that Python A does everything that Perl A does.
Possibly *better* than the Perl module, since if you don't have a test
suite for it, it probably has many hidden bugs.

Continue in this way with the rest of the modules. At the end, you will have
a full test suite against the entire collection of modules.



-- 
Steven

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Refactor/Rewrite Perl code in Python

2011-07-24 Thread Dan Stromberg
On Sun, Jul 24, 2011 at 2:29 AM, Shashwat Anand anand.shash...@gmail.comwrote:

 I am working with a huge codebase of Perl.
 The code have zero documentation and zero unit-tests.
 It seems like a huge hack.


My condolences.  Er, actually, it sounds kind of fun.

The underlying database schema is horrid.
 So I want to rewrite the whole of it in Python.


Good choice.


 How do I start ?


You're probably going to need to learn a lot about the perl code - it's
probably a good idea to come up with unit, integration and system tests for
it - in perl; document it; and diagram it using something like autodia.

Then after you know what's going on inside and outside the perl, you're
better equipped to rewrite into python.

If you write your automated perl tests in a straightforward way, they can be
mostly straightforwardly translated to python - to get an apples to apples
comparison of how each is functioning.

If you do this module by module, you're less likely to run into problems,
but you're also more likely to preserve some of the original code's
oddities.


 The idea is to rewrite module by module.

But how to make sure code doesn't break ?


See above.


 How can I import perl and python codes in each other ?


I'm not confident you can, unless perhaps you find that you can use an
alternative VM like Parrot.  However, many languages on Parrot are not
complete.
-- 
http://mail.python.org/mailman/listinfo/python-list