Yes. But, if you prefer a longer answer:
Class B inherits from class A. When implementing B's __init__ function, we may call A's init by writing:
super(B, self).__init__(arguments of A's __init__)
Is it really necessary? After all, in C++ or Java the constructor of base class is called automatically, so shouldn't it be called automatically in Python as well?
The point is that __init__ is not a constructor. Python objects are constructed with __new__. __init__ is used to initialize an object with concrete values, either defaults or passed as __init__'s parameters.
Need more details? Read Python docs at http://docs.python.org/2/reference/datamodel.html#object.__new__
I have had the rare opportunity of watching and being part of the change that the software industry has gone through throughout over 20 last years. This blog is a collection of my reflections on pursuing agility path. It includes observations and advice regarding development teams and notes on useful engineering practices. Enjoy! Piotr Górak.
Monday, May 6, 2013
Thursday, April 18, 2013
Code Kata: text game from 1982
The goal is to implement a text-based game in which the player walks through dungeons in order to accomplish a task. The basic characteristics of an implementation are as follows:
- the game generates random dungeons as a group of ROOMS and PATHS that join the ROOMS
- the generation does not leave unreachable ROOMS
- the user is presented with the information about the ROOM they are in and the ROOMS reachable directly from the current ROOM
- the user can move from the current ROOM to the directly reachable ROOMS by entering a command
- We do all of the implementation using "TDD, as if you meant it", of course
- Initially, the goal may be simply to get to a given ROOM
- Then, we may start adding attributes to ROOMS; a possible attribute is something that the user can collect, such as diamonds; N diamonds are placed in the dungeon and the game is finished when the user collects all of them; additional attributes can be used to describe the look a ROOM
- When that's done, we can refactor our implementation so that we do not use IF statements
- When that's done, we can refactor our implementation so that we do not use for/while loops
- We can work on the implementation a little bit more to get rid of excessive tabs (let's allow only up to two tabs in the body of a function, per Robert Martin's suggestion)
- We can get better by limiting the number of lines of a function (how about < 5 lines per function?)
- I'm guessing you did all of this with classes and objects; how would you do it with pure functions and no objects?
Tuesday, April 9, 2013
Python profiling for beginners
def bar(i):
return i*i
def foo():
for i in range(0,1000000):
bar(i)
Let's try to use these two silly functions to do a profiling exercise.
First of all, we need to import cProfile. And then call: cProfile.run('foo()')
Output (from my laptop):
1000004 function calls in 3.564 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.926 1.926 3.564 3.564 <pyshell#11>:1(foo)
1000000 1.638 0.000 1.638 0.000 <pyshell#9>:1(bar)
1 0.000 0.000 3.564 3.564 <string>:1(<module>)
1 0.000 0.000 3.564 3.564 {built-in method exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
At the first glance, it may look criptic, but: the total time is the time spent in a function excluding the time spent in callees. The cummulative time is the time spent in a function including the time spent in callees. Therefore, these two times are equal for bar function. ncalls and percall are self-explanatory.
But we can go further. I highly recommend trying out a GUI application that can read the cProfile output, such as RunSnakeRun from http://www.vrplumber.com/programming/runsnakerun For this simple case it'd be useless, but for much more complex call tree, it is of great help.
In order to use it, we need to run cProfile giving it the dump file name as the second argument:
cProfile.run('foo()', 'dump.txt')
return i*i
def foo():
for i in range(0,1000000):
bar(i)
Let's try to use these two silly functions to do a profiling exercise.
First of all, we need to import cProfile. And then call: cProfile.run('foo()')
Output (from my laptop):
1000004 function calls in 3.564 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.926 1.926 3.564 3.564 <pyshell#11>:1(foo)
1000000 1.638 0.000 1.638 0.000 <pyshell#9>:1(bar)
1 0.000 0.000 3.564 3.564 <string>:1(<module>)
1 0.000 0.000 3.564 3.564 {built-in method exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
At the first glance, it may look criptic, but: the total time is the time spent in a function excluding the time spent in callees. The cummulative time is the time spent in a function including the time spent in callees. Therefore, these two times are equal for bar function. ncalls and percall are self-explanatory.
But we can go further. I highly recommend trying out a GUI application that can read the cProfile output, such as RunSnakeRun from http://www.vrplumber.com/programming/runsnakerun For this simple case it'd be useless, but for much more complex call tree, it is of great help.
In order to use it, we need to run cProfile giving it the dump file name as the second argument:
cProfile.run('foo()', 'dump.txt')
Subscribe to:
Posts (Atom)
See also
-
We may often come across a piece of code that was written without Unit Tests at all. In addition, the piece of code may be dealing with IO l...
-
Google Mock provides several ways to maintain state inside mock objects. One way of implementing state maintenance is with SaveArg . Consid...
-
Requirements have a long history in software industry. We all have heard or read terms like: requirements definition, requirements managemen...
-
Google Mock provides a way to return newly created objects from a mock method. Suppose we have a Generator class that is supposed to ...
-
Can we verify that a mock object is properly destroyed? Of course! There is a couple of subtle differences between mocking regular func...