Is there an option of some sort in the Dr. Python interpreter that would allow one to re-run the same output results after making adjustments to the code.

Example:
I run an example of source code and receive an output result. I make changes to the code. I now am able to run the same code (with the same output) to see how the new code affects a particular output result.

This just came to mind today while doing testing on a personal Python project. This would really save time and allow me to see reactions to adjusted code immediatly rather than hoping to come upon the same bug by running code again and again manually.

I am sure something like this exists in compilers in general, I imagine, but I have never made use of it.

Thanks for any help in advance.

sharky_machine

Sharky,

DrPython is not a compiler nor an interpreter, it is simply an fancy editor that allows you to run code from.

I assume from your question that you want to retain the previous outputs in your output window, so you can compare them?

Do you mean some kind of automated testing, where you can pass the same input to the code each time?

There are ways of doing that that are really sophisticated, but I usually just wrap the code in some kind of test() function that tests each class or function.

Writing the test() is a bear, but then you can just run the file, type test(), and relax. I mean, go and fix the bugs. At least in my case.
:lol:
Jeff

You could write a small Python program that will run your script repeatedly (put a time delay into the loop) with arguments you give it ...

# run an external program from within Python code with
# subprocess.call(["program-name", "arg1", "arg2", ...])
import subprocess

# part of a loop
subprocess.call(["C:/Python25/Python.exe", "MyScript.py", "arg1", "arg2"])

Then write your MyScript.py in such a way that the output goes to a file with a time/date stamp in the filename. I think there is a suggestion how to do this in the "Starting Python" sticky. Finally compare the files with another Python program.

Matty,
I was thinking about your question. Python has a module to do automatic unit testing, appropriately called 'unittest'. Take a look in the Python manual, there are examples.

Intrigued, I coded up a simple unittest example.

import unittest

# The class to test
class Rectangle(object):

    def __init__(self, w, h):
        self.width = w
        self.height = h

    def get_width(self):
        return self._w

    def set_width(self, w):
        if w == None:
            raise ValueError
        self._w = w

    width = property(get_width, set_width)

    def get_height(self):
        return self._h

    def set_height(self, h):
        if h == None:
            raise ValueError
        self._h = h

    height = property(get_height, set_height)
    
    def area(self):
        return self.height * self.width


class TestRectangle(unittest.TestCase):  # the magic occurs here
                                                           # by subclassing TestCase

    def setUp(self):
        self.test_cases = [(2,3),(0,5),(-2.5,6)]
        self.test_widths = [2,0,-2.5]
        self.test_heights = [3,5,6]
        self.test_areas = [6,0,-15] 
        # the last element could be the subject of debate:
        # Should rectangles be allowed to have signed area and sides?
        # In the interest of physics, I decided Yes' (think flux here), but 
        # here in the test suite is the place that debate amongst the 
        # programming team could occur.

        self.error_cases = [(None,3),(5,None),(None,None)]
        self.error_results = [ValueError,ValueError,ValueError]

    def testHeight(self):

        self.Rects = [Rectangle(*x) for x in self.test_cases]
        self.assertEqual([x.height for x in self.Rects], self.test_heights)

    def testWidth(self):

        self.Rects = [Rectangle(*x) for x in self.test_cases]
        self.assertEqual([x.width for x in self.Rects], self.test_widths)

    def testArea(self):

        self.Rects = [Rectangle(*x) for x in self.test_cases]
        self.assertEqual([x.area() for x in self.Rects], self.test_areas)

    def testErrors(self):

        errors = dict(zip(self.error_cases, self.error_results))
        for x in errors:
            w,h = x
            self.assertRaises(errors[x], Rectangle, w, h)

if __name__ == "__main__":

    unittest.main()  #automagically creates an instance of my
                           # TestRectangle class, and runs each method.

Here's the output with all Rectangle methods broken:

FFEE
======================================================================
ERROR: testHeight (__main__.TestRectangle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 50, in testHeight
    self.assertEqual([x.height for x in self.Rects], self.test_heights)
  File "C:/Python24/unittest_test.py", line 21, in get_height
    return self._h
AttributeError: 'Rectangle' object has no attribute '_h'

======================================================================
ERROR: testWidth (__main__.TestRectangle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 55, in testWidth
    self.assertEqual([x.width for x in self.Rects], self.test_widths)
  File "C:/Python24/unittest_test.py", line 10, in get_width
    return self._w
AttributeError: 'Rectangle' object has no attribute '_w'

======================================================================
FAIL: testArea (__main__.TestRectangle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 60, in testArea
    self.assertEqual([x.area() for x in self.Rects], self.test_areas)
AssertionError: [None, None, None] != [6, 0, -15]

======================================================================
FAIL: testErrors (__main__.TestRectangle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 67, in testErrors
    self.assertRaises(errors[x], Rectangle, w, h)
AssertionError: ValueError not raised

----------------------------------------------------------------------
Ran 4 tests in 0.015s

FAILED (failures=2, errors=2)

Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 71, in -toplevel-
    ut.main()
  File "C:\Python24\lib\unittest.py", line 759, in __init__
    self.runTests()
  File "C:\Python24\lib\unittest.py", line 797, in runTests
    sys.exit(not result.wasSuccessful())
SystemExit: True

and with all Rectangle methods set to their correct code:

....
----------------------------------------------------------------------
Ran 4 tests in 0.015s

OK

Traceback (most recent call last):
  File "C:/Python24/unittest_test.py", line 68, in -toplevel-
    unittest.main()
  File "C:\Python24\lib\unittest.py", line 759, in __init__
    self.runTests()
  File "C:\Python24\lib\unittest.py", line 797, in runTests
    sys.exit(not result.wasSuccessful())
SystemExit: False

My question: is that last bit normal? Why the complicated 'sys.exit(not result.wasSuccessful())'?

Anyways, the OK is the sign that all is well with the world.

Jeff

Jeff, I tested your code sample and did not get the goofy traceback. However, I streamlined the indent on some of your comment lines.

I am using Python24 on a Windows XP machine.

This article has been dead for over six months. Start a new discussion instead.