0

My code is:

import time
class Stopwatch (object):
    def start (self):
        self.beginningTime = time.time()
        self.fehlerzahl = 1
    def stop (self):
        self.endTime = time.time()
        self.time = self.endTime - self.beginningTime
    def fehler(self):
        self.fehlerzahl = self.fehlerzahl + 1;
    def getTime (self):
        return(self.time + self.fehlerzahl * 2)

When I call the fehler() (Function names are in German) funtction, python gives me the following error trace:

Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import stopwatch
>>> c = stopwatch.Stopwatch()
>>> c.fehler()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "stopwatch.py", line 10, in fehler
    self.fehlerzahl = self.fehlerzahl + 1;
AttributeError: 'Stopwatch' object has no attribute 'fehlerzahl'
>>> 

Please tell me why it doesn't run.

Thanks

Laurenz
  • 51
  • 2
  • 1
    You never `start`ed the stopwatch. In other words, you never set/initialized `self.fehlerzahl`, but you try to use its value in the `fehler` method. –  Nov 27 '14 at 13:52
  • 2
    http://stackoverflow.com/questions/625083/python-init-and-self-what-do-they-do may help: make use of `__init__()` to set attributes. –  Nov 27 '14 at 13:53

2 Answers2

3

The problem here is that the fehler() function is trying to increment an attribute that doesn't exist yet.

From your code, the start() function is where the fehlerzahl attribute is defined. You'll have to call this function first before you call fehler():

import stopwatch
c = stopwatch.Stopwatch()
c = stopwatch.start()
c.fehler()

Your variables need to be defined before you try to manipulate them. You can either call the start() function first or define the fehlerzahl earlier in the code; Perhaps in an __init__ function.

From the OP's comment it seems that an assumption was made that the start() function is the class constructor - this is not the case. A python class constructor is named __init__ so essentially all that needs to be done is to change the function name start to __init__.

Community
  • 1
  • 1
Lix
  • 47,311
  • 12
  • 103
  • 131
  • Thank you for your response! Sorry for the stupid question. Actually I'm trying to code a whole project within 2 hours. I thought start() is the constructor ;-) – Laurenz Nov 27 '14 at 13:54
  • @Laurenz - coding under pressure :) Always fun! Glad to help, good luck and happy coding! – Lix Nov 27 '14 at 13:55
  • @Laurenz it's not, but you can make it one! Just add `__init__ = start` to your class definition. – ch3ka Nov 27 '14 at 13:55
  • @ch3ka - I wouldn't recommend overriding the `__init__` constructor like that. It would make more sense (and preserve readability) to use `__init__` as it was intended. – Lix Nov 27 '14 at 13:56
  • @Lix `__init__ = start` does not override anything, it's exactly the same as renaming `start` to `__init__` (minus the remaining alias). – ch3ka Nov 27 '14 at 13:57
  • 1
    @ch3ka - when reading the code of a class, a programmer will always look for the `__init__` function - it's something that everyone expects to exist - in order to make readable code the original name should be preserved. You're right, however that it doesn't make a difference to the actual behavior of the code; I'm referencing the readability and thinking of the next programmer 6 months later who would be looking at this code. – Lix Nov 27 '14 at 13:59
  • 1
    @Laurenz: And `stop` is not the destructor. In fact, there is no real destructor in Python (`__del__` doesn't count). – Matthias Nov 27 '14 at 14:03
  • @Lix I well see your point, and you're right in that one should not really teach such practise; but OTOH relying on that function/method definitions always start with `def` is just plain wrong. Functions are first order citizens for a very good reason, and `lambda` exists, too. – ch3ka Nov 27 '14 at 14:11
0

You forgot to call start() on the stopwatch.