[Tutor] Error in class definition of __init__

Alan Gauld alan.gauld at yahoo.co.uk
Thu Feb 15 04:13:51 EST 2018


On 15/02/18 01:27, Leo Silver wrote:
> Hello.
> 
> I'm trying to create a class to represent products which includes a list of
> volume based pricing and sets the first of these as the unit price:
> 
>     def __init__(self, RatePlanID):
>         self.id = RatePlanID
>         self.name = RatePlans.toggleids[self.id]
>         self.pricing = RatePlans.pricebreaks[self.name]
>         self.unitprice = RatePlans.pricebreaks[self.name][0]
> 

You could simolify the last line to:

         self.unitprice = self.pricing[0]

BTW This process is poor practice since you are effectively
reading the data from a global object (whose definition you don't
share) It would be better to pass the RatePlans into the
init() ass a parameter. Also its bad OO practice to extract
lots of data out of another object to store in your own.
It suggests that either you should be storing a reference to the
object(self.ratePlan, say) or that your RatePlans collection
should be storing some other kind of object which can
be extracted by init (a PriceBreak maybe):

self.foo = RatePlans.getObject(RatePlanID)

Anyway, design issues aside...

> This code gives an IndexError:
> ...
>     self.unitprice = RatePlans.pricebreaks[self.name][0]
> IndexError: list index out of range
> 
> However, the same code with the last line changed to:
>         self.unitprice = RatePlans.pricebreaks[self.name][:1]

These do very different things.
The first uses indexing to extract a single item out of a collection.
The second creates a new collection based on an existing one, but it
does not require the slice values to exist, it will use defaults
if they don't.

> seems to work OK, 

When you say "work" I assume you mean you don;t get an error,
rather than that you have tested it and the unitprice
contains the correct data?

> The list I'm trying to process is:
> [(1, 21.0), (100, 19.6), (250, 18.4), (500, 17.6), (1000, 16.7), (2500,
> 14.7), (10000, 13.7)]

Which list is this in your code?
Is it RatePlans or is it RatePlans.pricebreaks?
Or is it the list returned by RatePlans.pricebreaks[self.name]?
You need to be more specific. I'll assume the last one...

> and a cut and paste into the IDLE GUI let's me process it exactly as I
> expect (including picking the second element of the tuple, the price rather
> than the volume level):
>>>> [(1, 21.0), (100, 19.6), (250, 18.4), (500, 17.6), (1000, 16.7), (2500,
> 14.7), (10000, 13.7)][0][1]

But that's not what you are doing in your code.
You are using variables populated from another object (RatePlans).
Unless you have printed out the values in self.name etc to confirm
they are a valid list. The error message suggests you are retrieving
an empty list. Have you checked?

> What am I missing about the class definition that won't let me put this
> class in the init call?

Nothing, I think the problem is in your RatePlans data.
Coupled to the fact that you are trying to use some very
dodgy OO design.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list