Is this a good way to work with init and exception

2015-07-19 Thread Cecil Westerhof
I am using libturpial to post things on Twitter. But sometimes I get a
ServiceOverCapacity exception. So I wrote the following code.

==
class InitAlreadyDoneError(Exception):
pass


# Functions
def init(max_tries = 5, wait_time = 60):
global _core

if _core != None:
raise InitAlreadyDoneError
tries = 0
while True:
try:
_core = Core()
break
except ServiceOverCapacity:
tries += 1
sys.stderr.write('Tried to init _core it {0} times\n'.format(tries))
sys.stderr.flush()
if tries = max_tries:
raise
time.sleep(wait_time)
==

Is this the correct way to work user defined exceptions, or should I
also define a default message?

I use this in the following way:
import twitterDecebal
twitterDecebal.init()

Because you can not give parameters with an import as far as I can
see. Is this a good way to do this, or is there a better way?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Chris Angelico
Reordering/interleaving your post to respond to different parts together.

On Sun, Jul 19, 2015 at 8:35 PM, Cecil Westerhof ce...@decebal.nl wrote:
 I am using libturpial to post things on Twitter. But sometimes I get a
 ServiceOverCapacity exception. So I wrote the following code.

 ==
 class InitAlreadyDoneError(Exception):
 pass

 Is this the correct way to work user defined exceptions, or should I
 also define a default message?

I'd start by looking through the exception hierarchy for something
appropriate to subclass. In this case, you're basically saying run
init() exactly once, and if you run it a second time, I'll throw back
an error, which probably doesn't have any logical match, so directly
subclassing Exception would be correct. But you might decide that
subclassing ValueError or RuntimeError is more appropriate.

 # Functions
 def init(max_tries = 5, wait_time = 60):
 global _core

 if _core != None:
 raise InitAlreadyDoneError

This is where I'd add a message, if you want one. But it looks to me
as if there's never going to be any other place that raises this, so
the message would be redundant. InitAlreadyDoneError implies you
called init() after someone else called init().

(Side point: It might be a neat courtesy to let people call init
again, or maybe a try_init() that won't error out if already
initialized.)

 tries = 0
 while True:
 try:
 _core = Core()
 break
 except ServiceOverCapacity:
 tries += 1
 sys.stderr.write('Tried to init _core it {0} 
 times\n'.format(tries))
 sys.stderr.flush()
 if tries = max_tries:
 raise
 time.sleep(wait_time)
 ==


 I use this in the following way:
 import twitterDecebal
 twitterDecebal.init()

 Because you can not give parameters with an import as far as I can
 see. Is this a good way to do this, or is there a better way?

Parameterized imports aren't possible, correct. What I'd look at here
is a more explicit instantiation. Something like:

import twitterDecebal
twitter = twitterDecebal.twitterDecebal(5, 60)

Especially since it's something that does a ton of network operations
and all sorts of sleeps and timeouts, I would strongly recommend NOT
doing this on import, even if you could. If you don't absolutely
_need_ it to be global, it'd be cleanest to make it a class that you
construct.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Cecil Westerhof
On Sunday 19 Jul 2015 14:59 CEST, Chris Angelico wrote:

 Reordering/interleaving your post to respond to different parts
 together.

 On Sun, Jul 19, 2015 at 8:35 PM, Cecil Westerhof ce...@decebal.nl wrote:
 I am using libturpial to post things on Twitter. But sometimes I
 get a ServiceOverCapacity exception. So I wrote the following code.

 ==
 class InitAlreadyDoneError(Exception): pass

 Is this the correct way to work user defined exceptions, or should
 I also define a default message?

 I'd start by looking through the exception hierarchy for something
 appropriate to subclass. In this case, you're basically saying run
 init() exactly once, and if you run it a second time, I'll throw
 back an error, which probably doesn't have any logical match, so
 directly subclassing Exception would be correct. But you might
 decide that subclassing ValueError or RuntimeError is more
 appropriate.

Subclassing ValueError or RuntimeError looks wrong to me.


 # Functions
 def init(max_tries = 5, wait_time = 60):
 global _core

 if _core != None:
 raise InitAlreadyDoneError

 This is where I'd add a message, if you want one. But it looks to me
 as if there's never going to be any other place that raises this, so
 the message would be redundant. InitAlreadyDoneError implies you
 called init() after someone else called init().

I thought so, but just wanted to be sure. ;-)


 (Side point: It might be a neat courtesy to let people call init
 again, or maybe a try_init() that won't error out if already
 initialized.)

I changed it to:

def init(max_tries = 5, wait_time = 60, reinit_allowed = False):
global _core

if (_core != None) and not reinit_allowed:
raise InitAlreadyDoneError


 I use this in the following way:
 import twitterDecebal
 twitterDecebal.init()

 Because you can not give parameters with an import as far as I can
 see. Is this a good way to do this, or is there a better way?

 Parameterized imports aren't possible, correct. What I'd look at
 here is a more explicit instantiation. Something like:

 import twitterDecebal
 twitter = twitterDecebal.twitterDecebal(5, 60)

I worked with default values, because I thought that would be a good
idea. I should remove the default values?


 Especially since it's something that does a ton of network
 operations and all sorts of sleeps and timeouts, I would strongly
 recommend NOT doing this on import, even if you could. If you don't
 absolutely _need_ it to be global, it'd be cleanest to make it a
 class that you construct.

In principal I only mend that before you use the twitter functions you
need to do the init. (And because of the ton of functions I wanted a
reinit to be an error.) In my case it is exactly below the import.
Because I use it in a script and except one situation _core is always
used. So I thought it to be more clear.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Chris Angelico
On Mon, Jul 20, 2015 at 8:19 AM, Cecil Westerhof ce...@decebal.nl wrote:
 If two modules import the same module, they get two references to
 that same module, not two separate module instances. Since your
 parameters appear only to affect the initialization itself, this is
 not likely to be a problem (it's not like you'll need to
 authenticate with two different sets of credentials, for instance),
 but it will mean that the second one will import an
 already-initialized module. That's why I suggested the try_init
 function which would quietly return an immediate success if the
 module had already been initialized. But if this isn't going to be
 an issue, then your code's fine.

 Good to know. I would expect two different instances.

 I agree that in my case it would not be a problem, but I put the code
 on GitHub:
 
 https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py
 I should do my best to circumvent nasty surprises for users of the
 code. Someone else could use several Twitter accounts at the same
 time. Is there a way to do this?

Does the instantiation of Core() involve authentication? Is it
possible to call Core() more than once and use different accounts?
Your send_message() takes an account identifier, so it might be you
don't need separate accounts. But if, just very occasionally, you do
need multiple, here's a possible design style: Have init() return the
Core as well as stashing it in _core, and then have send_message()
take an optional keyword argument (in 3.x, keyword-only) to choose a
different core. That way, it'll by default use the most recently
initialized core, but you can create multiple and manage them yourself
if you so choose. (Obviously you'd use reinit_allowed=True for all the
initializations.)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Cecil Westerhof
On Sunday 19 Jul 2015 23:08 CEST, Chris Angelico wrote:

 On Mon, Jul 20, 2015 at 5:10 AM, Cecil Westerhof ce...@decebal.nl wrote:
 I think it's fine, then. As long as it makes absolutely no sense
 to have two separately-initialized twitter connections, and as
 long as it's okay for two separate modules to both import this and
 to then share state, then what you have is fine.

 I do not see myself doing this, but I like to know ‘everything’.
 When I have a program with two different modules that both import
 this, they would get in each-others way? How?

 If two modules import the same module, they get two references to
 that same module, not two separate module instances. Since your
 parameters appear only to affect the initialization itself, this is
 not likely to be a problem (it's not like you'll need to
 authenticate with two different sets of credentials, for instance),
 but it will mean that the second one will import an
 already-initialized module. That's why I suggested the try_init
 function which would quietly return an immediate success if the
 module had already been initialized. But if this isn't going to be
 an issue, then your code's fine.

Good to know. I would expect two different instances.

I agree that in my case it would not be a problem, but I put the code
on GitHub:

https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py
I should do my best to circumvent nasty surprises for users of the
code. Someone else could use several Twitter accounts at the same
time. Is there a way to do this?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Chris Angelico
On Mon, Jul 20, 2015 at 5:10 AM, Cecil Westerhof ce...@decebal.nl wrote:
 I think it's fine, then. As long as it makes absolutely no sense to
 have two separately-initialized twitter connections, and as long as
 it's okay for two separate modules to both import this and to then
 share state, then what you have is fine.

 I do not see myself doing this, but I like to know ‘everything’. When
 I have a program with two different modules that both import this,
 they would get in each-others way? How?

If two modules import the same module, they get two references to that
same module, not two separate module instances. Since your parameters
appear only to affect the initialization itself, this is not likely to
be a problem (it's not like you'll need to authenticate with two
different sets of credentials, for instance), but it will mean that
the second one will import an already-initialized module. That's why I
suggested the try_init function which would quietly return an
immediate success if the module had already been initialized. But if
this isn't going to be an issue, then your code's fine.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Cecil Westerhof
On Monday 20 Jul 2015 00:40 CEST, Chris Angelico wrote:

 On Mon, Jul 20, 2015 at 8:19 AM, Cecil Westerhof ce...@decebal.nl wrote:
 If two modules import the same module, they get two references to
 that same module, not two separate module instances. Since your
 parameters appear only to affect the initialization itself, this
 is not likely to be a problem (it's not like you'll need to
 authenticate with two different sets of credentials, for
 instance), but it will mean that the second one will import an
 already-initialized module. That's why I suggested the try_init
 function which would quietly return an immediate success if the
 module had already been initialized. But if this isn't going to be
 an issue, then your code's fine.

 Good to know. I would expect two different instances.

 I agree that in my case it would not be a problem, but I put the
 code on GitHub:
 https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py
 I should do my best to circumvent nasty surprises for users of the
 code. Someone else could use several Twitter accounts at the same
 time. Is there a way to do this?

 Does the instantiation of Core() involve authentication? Is it
 possible to call Core() more than once and use different accounts?
 Your send_message() takes an account identifier, so it might be you
 don't need separate accounts. But if, just very occasionally, you do
 need multiple, here's a possible design style: Have init() return
 the Core as well as stashing it in _core, and then have
 send_message() take an optional keyword argument (in 3.x,
 keyword-only) to choose a different core. That way, it'll by default
 use the most recently initialized core, but you can create multiple
 and manage them yourself if you so choose. (Obviously you'd use
 reinit_allowed=True for all the initializations.)

You are right: core is a general initialisation, so in this case
nothing to worry about. :-D

When I write something where it could make a difference, I should use
your tip.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Cecil Westerhof
On Sunday 19 Jul 2015 20:11 CEST, Chris Angelico wrote:

 Parameterized imports aren't possible, correct. What I'd look at
 here is a more explicit instantiation. Something like:

 import twitterDecebal
 twitter = twitterDecebal.twitterDecebal(5, 60)

 I worked with default values, because I thought that would be a
 good idea. I should remove the default values?

 No no, the default values are good. I just gave an example that
 didn't use them, as that's where you actually need the call. If
 you're always going to use the defaults, well, there's not a lot of
 point having the function. But if you often use the defaults (or one
 of them), and occasionally override it, then what you have is good
 design.

In my case I think the defaults are good. (But I do not know how I
will use the function in the future. ;-) ) But I want to share it on
GitHub and it would be possible that for someone else my defaults are
not correct and then it is nice when they can be overridden.


 I think it's fine, then. As long as it makes absolutely no sense to
 have two separately-initialized twitter connections, and as long as
 it's okay for two separate modules to both import this and to then
 share state, then what you have is fine.

I do not see myself doing this, but I like to know ‘everything’. When
I have a program with two different modules that both import this,
they would get in each-others way? How?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a good way to work with init and exception

2015-07-19 Thread Chris Angelico
On Mon, Jul 20, 2015 at 2:46 AM, Cecil Westerhof ce...@decebal.nl wrote:
 On Sunday 19 Jul 2015 14:59 CEST, Chris Angelico wrote:

 Reordering/interleaving your post to respond to different parts
 together.

 On Sun, Jul 19, 2015 at 8:35 PM, Cecil Westerhof ce...@decebal.nl wrote:
 I am using libturpial to post things on Twitter. But sometimes I
 get a ServiceOverCapacity exception. So I wrote the following code.

 ==
 class InitAlreadyDoneError(Exception): pass

 Is this the correct way to work user defined exceptions, or should
 I also define a default message?

 I'd start by looking through the exception hierarchy for something
 appropriate to subclass. In this case, you're basically saying run
 init() exactly once, and if you run it a second time, I'll throw
 back an error, which probably doesn't have any logical match, so
 directly subclassing Exception would be correct. But you might
 decide that subclassing ValueError or RuntimeError is more
 appropriate.

 Subclassing ValueError or RuntimeError looks wrong to me.

Sure. Like I said, directly subclassing Exception seemed the most
logical route. Just threw that out there as a possibility.

 (Side point: It might be a neat courtesy to let people call init
 again, or maybe a try_init() that won't error out if already
 initialized.)

 I changed it to:
 
 def init(max_tries = 5, wait_time = 60, reinit_allowed = False):
 global _core

 if (_core != None) and not reinit_allowed:
 raise InitAlreadyDoneError
 

That works, too!

 I use this in the following way:
 import twitterDecebal
 twitterDecebal.init()

 Because you can not give parameters with an import as far as I can
 see. Is this a good way to do this, or is there a better way?

 Parameterized imports aren't possible, correct. What I'd look at
 here is a more explicit instantiation. Something like:

 import twitterDecebal
 twitter = twitterDecebal.twitterDecebal(5, 60)

 I worked with default values, because I thought that would be a good
 idea. I should remove the default values?

No no, the default values are good. I just gave an example that didn't
use them, as that's where you actually need the call. If you're always
going to use the defaults, well, there's not a lot of point having the
function. But if you often use the defaults (or one of them), and
occasionally override it, then what you have is good design.

 Especially since it's something that does a ton of network
 operations and all sorts of sleeps and timeouts, I would strongly
 recommend NOT doing this on import, even if you could. If you don't
 absolutely _need_ it to be global, it'd be cleanest to make it a
 class that you construct.

 In principal I only mend that before you use the twitter functions you
 need to do the init. (And because of the ton of functions I wanted a
 reinit to be an error.) In my case it is exactly below the import.
 Because I use it in a script and except one situation _core is always
 used. So I thought it to be more clear.

I think it's fine, then. As long as it makes absolutely no sense to
have two separately-initialized twitter connections, and as long as
it's okay for two separate modules to both import this and to then
share state, then what you have is fine.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list