Re: [BangPypers] Return values
On Thu, Sep 25 2014, Saager Mhatre wrote: [...] Alternatively, would it be possible to model Stats/StatsList as a composite hierarchy (potentially with Courtesy Implementations http://martinfowler.com/bliki/CourtesyImplementation.html)? [...] I didn't know about Courtesy implementations till now. Thanks. I'm not really convinced with Fowlers argument and I didn't like the solution but it's still an interesting patterns. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Thu, Sep 25 2014, Saager Mhatre wrote: [...] Alternatively, would it be possible to model Stats/StatsList as a composite hierarchy (potentially with Courtesy Implementations http://martinfowler.com/bliki/CourtesyImplementation.html)? [...] I didn't know about Courtesy implementations till now. Thanks. I'm not really convinced with Fowlers argument and I didn't like the solution but it's still an interesting pattern. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 6:53 AM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: On Sat, Sep 20 2014, Anand Chitipothu wrote: [...] Oh, that feels like PHP. That style seems to be popular in that side of the world. It might be a good idea to add consolidate method on the return value. Something like: class StatsList(list): def consolidate(self): .. print get_stats(..) print get_stats(..).consolidate() [...] That's a nice solution. It's similar to what Senthil suggested but I like the API better. Alternatively, would it be possible to model Stats/StatsList as a composite hierarchy (potentially with Courtesy Implementations http://martinfowler.com/bliki/CourtesyImplementation.html)? - d ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
[BangPypers] Return values
I've recently come across something that I'd like some comments on. It's a stylistic issue so not something that there's an objective answer for. Nevertheless. I have a function that gets some statistics from some source and returns it to the user as a Stats object. Let's call it get_stats. This has a parameter `consolidate`. If consolidate is True, it will combine all the statistics and return just one Stats object. If not, it will return a list of Stats objects. The problem now is that this function sometimes returns a single thing and some times a list. I don't like this since I have to alter my calling code to handle this. I'm surprised that I've never hit this before and I'm not really sure how to handle it. Comments? -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
Couple of approaches: - Break the api into two. get_stats and get_stats_consolidated. This way, the caller who doesn't know what is your default value of consolidated argument is will not be confused. - Change the return value to be a list always. Without consolidated set, it will just be [Stats], else [stat1, stat2, stat3..] - More descriptive return value could be a dict: { 'consolidated': True|False 'value' : [] } Regards, Harish On Sat, Sep 20, 2014 at 2:44 PM, shankha shankhabaner...@gmail.com wrote: Can you please tell at how many places you make the call. That is the problem with these stupid dynamic languages :-) On Sep 20, 2014 2:35 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: I've recently come across something that I'd like some comments on. It's a stylistic issue so not something that there's an objective answer for. Nevertheless. I have a function that gets some statistics from some source and returns it to the user as a Stats object. Let's call it get_stats. This has a parameter `consolidate`. If consolidate is True, it will combine all the statistics and return just one Stats object. If not, it will return a list of Stats objects. The problem now is that this function sometimes returns a single thing and some times a list. I don't like this since I have to alter my calling code to handle this. I'm surprised that I've never hit this before and I'm not really sure how to handle it. Comments? -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 5:04 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: This has a parameter `consolidate`. If consolidate is True, it will combine all the statistics and return just one Stats object. If not, it will return a list of Stats objects. The problem now is that this function sometimes returns a single thing and some times a list. I don't like this since I have to alter my calling code to handle this. I'm surprised that I've never hit this before and I'm not really sure how to handle it. Comments? One option to me looks like, don't have consolidate as parameter for this function, but do the operation outside. Like providing a function called get_consolidated_stats, which will call get_stats and provide the consolidated result. The reason I am suggesting is, consolidation is one of the operation that be performed on the the collection and it seems that injecting that operation on the collection is 'limiting' the API. The other obvious options are. 1) Return a list, but when consolidate is sent, it is a single element list. # This hurts semantics and human understanding 2) Return a higher level object, (Stats object) which has a property called consolidate, which can be set, when it is invoked. # This makes it a bit complex. ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 2:34 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: I've recently come across something that I'd like some comments on. It's a stylistic issue so not something that there's an objective answer for. Nevertheless. I have a function that gets some statistics from some source and returns it to the user as a Stats object. Let's call it get_stats. This has a parameter `consolidate`. If consolidate is True, it will combine all the statistics and return just one Stats object. If not, it will return a list of Stats objects. The problem now is that this function sometimes returns a single thing and some times a list. I don't like this since I have to alter my calling code to handle this. I'm surprised that I've never hit this before and I'm not really sure how to handle it. Comments? Oh, that feels like PHP. That style seems to be popular in that side of the world. It might be a good idea to add consolidate method on the return value. Something like: class StatsList(list): def consolidate(self): .. print get_stats(..) print get_stats(..).consolidate() Anand ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
Hi Noufal Why not create two methods, get_stats() and get_stats_list(). Both can share logic in a common function which takes the consolidate flag - meaning your logic is localised to one point only. It makes for more readable code when called as well. Cheers Vivek On Sat, Sep 20, 2014 at 2:34 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: I've recently come across something that I'd like some comments on. It's a stylistic issue so not something that there's an objective answer for. Nevertheless. I have a function that gets some statistics from some source and returns it to the user as a Stats object. Let's call it get_stats. This has a parameter `consolidate`. If consolidate is True, it will combine all the statistics and return just one Stats object. If not, it will return a list of Stats objects. The problem now is that this function sometimes returns a single thing and some times a list. I don't like this since I have to alter my calling code to handle this. I'm surprised that I've never hit this before and I'm not really sure how to handle it. Comments? -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers -- *Vivek Ramakrishna* | Director | GSoft Services Pvt Ltd | www.globalsoft.com | +91 702 202 5880 ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Senthil Kumaran wrote: [...] One option to me looks like, don't have consolidate as parameter for this function, but do the operation outside. Like providing a function called get_consolidated_stats, which will call get_stats and provide the consolidated result. The reason I am suggesting is, consolidation is one of the operation that be performed on the the collection and it seems that injecting that operation on the collection is 'limiting' the API. [...] I thought of this. If I can, for example, implement __add__ for the stats, I can say something like consolidated_stats = sum(get_stats(), Stats()) My only objection was if the consolidation is not trivial or depends on the time of sampling, then it might be complex, if not impossible. Still, this seems like the neatest way to do it. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Anand Chitipothu wrote: [...] Oh, that feels like PHP. That style seems to be popular in that side of the world. It might be a good idea to add consolidate method on the return value. Something like: class StatsList(list): def consolidate(self): .. print get_stats(..) print get_stats(..).consolidate() [...] That's a nice solution. It's similar to what Senthil suggested but I like the API better. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Vivek Ramakrishna wrote: Hi Noufal Why not create two methods, get_stats() and get_stats_list(). Both can share logic in a common function which takes the consolidate flag - meaning your logic is localised to one point only. It makes for more readable code when called as well. [...] This approach (especially with many calls) will make the API really big. I don't remember but I've seen things with get_something, get_something_list, get_something_dict and what not which don't really help readability. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 2:50 PM, Senthil Kumaran sent...@uthcode.com wrote: One option to me looks like, don't have consolidate as parameter for this function, but do the operation outside. Like providing a function called get_consolidated_stats, which will call get_stats and provide the consolidated result. +1 to this. Having a method do two different things based on a flag is not a clean answer to anything. ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 4:18 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: On Sat, Sep 20 2014, Harish Vishwanath wrote: Couple of approaches: - Break the api into two. get_stats and get_stats_consolidated. This way, the caller who doesn't know what is your default value of consolidated argument is will not be confused. This explodes the API. It's similar to having two sort functions 'sort_increasing', and 'sort_decreasing' instead of just a single sort function with a flag to indicate ordering. I think the comparison is not strictly apples to apples. In case of sort ascending / descending flag parameterises the same sort algorithm. In your case, you do some additional things (loop through and add up stuff, perhaps) based on the value of the flag. That is very different. ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Sriram Karra wrote: [...] I think the comparison is not strictly apples to apples. In case of sort ascending / descending flag parameterises the same sort algorithm. In your case, you do some additional things (loop through and add up stuff, perhaps) based on the value of the flag. That is very different. [...] Of course but the API should hide that in a neat way from you shouldn't it? If I have two switches an operation, I'd still like to have just one function. Not 4 representing all the combinations. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Sriram Karra wrote: [...] Having a method do two different things based on a flag is not a clean answer to anything. [...] That's a useful rule of thumb. Thank you. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 4:24 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: This approach (especially with many calls) will make the API really big. I don't remember but I've seen things with get_something, get_something_list, get_something_dict and what not which don't really help readability. That is true. But in my experience one of the biggest pain points in using Python has been dealing with 3rd party libraries that are poorly documented and have methods that return different types in different scenarios. It is living hell with said library is packaged and distributed as a pyd. I have come to avoid returning multiple types from a method - like the plague. All that in addition to your valid concern about exploding API. But your problem can be addressed by naming the functions after what they do - after all your consolidate function does something tangible other than just return a different type of data. ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 4:47 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: Of course but the API should hide that in a neat way from you shouldn't it? If I have two switches an operation, I'd still like to have just one function. Not 4 representing all the combinations. I will agree with you in principle. But I will note that we have gone from discussing a specific answer for a specific question to a sort of hypothetical situation. So I will have to stop right here. ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Sriram Karra wrote: [...] But your problem can be addressed by naming the functions after what they do - after all your consolidate function does something tangible other than just return a different type of data. [...] Let me give you a specific example. The psutils library has a function to get cpu times (idle, busy etc.). It can either do this per CPU (in which case, it will return a list of CPUTime objects, one per CPU) or give you the total (in which case, you'll get back a single CPUTime object). This is controlled by a per_cpu boolean flag. You can write a separate method to sum the individual times and then keep the conslidation outside get_cpu_times. The library chooses to sometimes return a list and sometimes return a single item. I don't like that. Now, I can write two functions like get_cpu_times and get_cpu_times_per_cpu. I don't particularly like that either. From the thread so far, Anand's solution is the one I like best. Although it's something tailored for my problem rather than a general pattern. -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20, 2014 at 5:15 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: From the thread so far, Anand's solution is the one I like best. Although it's something tailored for my problem rather than a general pattern. Anand's solution is good. But with the added context you have given - why are you not creating classes for CPU and Machine, with get_stats() and set_stats() methods for them? Something like: class CPU: def set_stats (self, cpu_t): self.cpu_stats = cpu_t def get_stats (self): return self.cpu_stats class Machine: def __init__ (self, n_cpus): self.cpus = [CPU() for i in range(0, n_cpus)] def fetch_stats (self): stats_list = psutils.get_cpu_stats() for i, stat in enumerate(stats_list): cpu[i].set_stats(stat) self.cpu_stats_summary = psutils.get_cpu_stats(summary=True) def get_cpu_stats_summary (self): return self.cpu_stats_summary ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
On Sat, Sep 20 2014, Sriram Karra wrote: [...] Anand's solution is good. But with the added context you have given - why are you not creating classes for CPU and Machine, with get_stats() and set_stats() methods for them? Something like: This is a higher level abstraction and something I might cook up depending on the application. My question was about the implementation of the get_cpu_stats function and its behaviour depending on the summary flag. [...] -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Return values
Dear Noufal, Have not gone through all the replies...so may be i am repeating...may be I am not in my senses :)) I would create a stats_bundle object, with members like stats_val and stats_list, which are initialized to None. So you always get a stats_bundle object which you can pass around to the handler function in the calling code. Since one of the above members is always going to be None, a simple check in the handler will be fine..i guess. But all this is stylistic...so it depends. Take care, Vishal Thanks and best regards, Vishal Sapre --- Please DONT print this email, unless you really need to. Save Energy Paper. Save the Earth. On Sat, Sep 20, 2014 at 9:57 PM, Sriram Karra karra@gmail.com wrote: On Sat, Sep 20, 2014 at 5:15 PM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: From the thread so far, Anand's solution is the one I like best. Although it's something tailored for my problem rather than a general pattern. Anand's solution is good. But with the added context you have given - why are you not creating classes for CPU and Machine, with get_stats() and set_stats() methods for them? Something like: class CPU: def set_stats (self, cpu_t): self.cpu_stats = cpu_t def get_stats (self): return self.cpu_stats class Machine: def __init__ (self, n_cpus): self.cpus = [CPU() for i in range(0, n_cpus)] def fetch_stats (self): stats_list = psutils.get_cpu_stats() for i, stat in enumerate(stats_list): cpu[i].set_stats(stat) self.cpu_stats_summary = psutils.get_cpu_stats(summary=True) def get_cpu_stats_summary (self): return self.cpu_stats_summary ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers