[Tutor] Error in class definition of __init__
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] 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] seems to work OK, although, I can't process it further and extract the second element of the pair. 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), (1, 13.7)] 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), (1, 13.7)][0][1] 21.0 What am I missing about the class definition that won't let me put this class in the init call? Thanks, Leo. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error in class definition of __init__
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] To debug your code print out the list and a few other things here with: print("name:", self.name) print("price breaks:", RatePlans.pricebreaks) print("pricebreaks[name]:", RatePlans.pricebreaks[self.name]) > self.unitprice = RatePlans.pricebreaks[self.name][0] > > 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] Slicing allows for the list to be shorter than specified: >>> items = [1, 2, 3] >>> items[:1] [1] >>> items[:100] [1, 2, 3] In your case it's an empty list: >>> items = [] >>> items[0] Traceback (most recent call last): File "", line 1, in IndexError: list index out of range >>> items[:1] [] > > seems to work OK, although, I can't process it further and extract the > second element of the pair. > > 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), (1, 13.7)] I'm pretty sure that's not what you'll see printed if you follow my advice and add those print() calls above. > 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), (1, 13.7)][0][1] > 21.0 > > What am I missing about the class definition that won't let me put this > class in the init call? This has nothing to do with __init__() specifically. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error in class definition of __init__
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), (1, 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), (1, 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 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor