Re: [BangPypers] Return values

2014-10-03 Thread Noufal Ibrahim KV
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

2014-10-03 Thread Noufal Ibrahim KV
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

2014-09-24 Thread Saager Mhatre
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

2014-09-20 Thread Noufal Ibrahim KV

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

2014-09-20 Thread Harish Vishwanath
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

2014-09-20 Thread Senthil Kumaran
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

2014-09-20 Thread Anand Chitipothu
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

2014-09-20 Thread Vivek Ramakrishna
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Sriram Karra
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

2014-09-20 Thread Sriram Karra
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Sriram Karra
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

2014-09-20 Thread Sriram Karra
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Sriram Karra
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

2014-09-20 Thread Noufal Ibrahim KV
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

2014-09-20 Thread Vishal
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