Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #89610 > unrolled thread
| Started by | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| First post | 2015-04-30 09:43 +0200 |
| Last post | 2015-04-30 14:30 +0200 |
| Articles | 10 — 5 participants |
Back to article view | Back to comp.lang.python
Let exception fire or return None Cecil Westerhof <Cecil@decebal.nl> - 2015-04-30 09:43 +0200
Re: Let exception fire or return None Dave Angel <davea@davea.name> - 2015-04-30 04:18 -0400
Re: Let exception fire or return None Cecil Westerhof <Cecil@decebal.nl> - 2015-04-30 11:13 +0200
Re: Let exception fire or return None Peter Otten <__peter__@web.de> - 2015-04-30 11:30 +0200
Re: Let exception fire or return None Cecil Westerhof <Cecil@decebal.nl> - 2015-04-30 13:26 +0200
Re: Let exception fire or return None Peter Otten <__peter__@web.de> - 2015-04-30 14:28 +0200
Re: Let exception fire or return None Cecil Westerhof <Cecil@decebal.nl> - 2015-04-30 16:53 +0200
Re: Let exception fire or return None Cecil Westerhof <Cecil@decebal.nl> - 2015-04-30 14:22 +0200
Re: Let exception fire or return None Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-04-30 14:05 +0200
Re: Let exception fire or return None Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-04-30 14:30 +0200
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-04-30 09:43 +0200 |
| Subject | Let exception fire or return None |
| Message-ID | <87bni6awol.fsf@Equus.decebal.nl> |
I have a function to fetch a message from a file:
def get_indexed_message(message_filename, index):
"""
Get index message from a file, where 0 gets the first message
"""
return open(expanduser(message_filename), 'r').readlines()[index].rstrip()
What is more the Python way: let the exception fire like this code
when index is to big, or catching it and returning None?
I suppose working zero based is OK.
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-04-30 04:18 -0400 |
| Message-ID | <mailman.119.1430381898.3680.python-list@python.org> |
| In reply to | #89610 |
On 04/30/2015 03:43 AM, Cecil Westerhof wrote: > I have a function to fetch a message from a file: > def get_indexed_message(message_filename, index): > """ > Get index message from a file, where 0 gets the first message > """ > > return open(expanduser(message_filename), 'r').readlines()[index].rstrip() > > What is more the Python way: let the exception fire like this code > when index is to big, or catching it and returning None? > > I suppose working zero based is OK. > Fire an exception. One advantage is that the exception will pinpoint exactly which line of the function had a problem. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-04-30 11:13 +0200 |
| Message-ID | <87pp6mvv1a.fsf@Equus.decebal.nl> |
| In reply to | #89611 |
Op Thursday 30 Apr 2015 10:18 CEST schreef Dave Angel: > On 04/30/2015 03:43 AM, Cecil Westerhof wrote: >> I have a function to fetch a message from a file: >> def get_indexed_message(message_filename, index): >> """ >> Get index message from a file, where 0 gets the first message >> """ >> >> return open(expanduser(message_filename), >> 'r').readlines()[index].rstrip() >> >> What is more the Python way: let the exception fire like this code >> when index is to big, or catching it and returning None? >> >> I suppose working zero based is OK. >> > > Fire an exception. > > One advantage is that the exception will pinpoint exactly which line > of the function had a problem. That is what I did. The only ‘problem’ is that they need to catch the error if they do not know the number of messages in the file. But they can use get_nr_of_messages for that. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-04-30 11:30 +0200 |
| Message-ID | <mailman.122.1430386245.3680.python-list@python.org> |
| In reply to | #89610 |
Cecil Westerhof wrote:
> I have a function to fetch a message from a file:
> def get_indexed_message(message_filename, index):
> """
> Get index message from a file, where 0 gets the first message
> """
>
> return open(expanduser(message_filename),
> 'r').readlines()[index].rstrip()
>
> What is more the Python way: let the exception fire like this code
> when index is to big, or catching it and returning None?
Fire an exception, but you may also allow the user to provide a default.
> I suppose working zero based is OK.
Not just OK, it's de rigueur.
You didn't ask for that, but
(1)
with open(...) as f:
return f.readlines()[index].rstrip()
is preferrable because it closes the file in a controlled way and
(2) you may want to take measures to limit memory usage, e. g.
assert index >= 0
try:
[line] = itertools.islice(f, index, index+1)
except ValueError:
raise IndexError
return line.rstrip()
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-04-30 13:26 +0200 |
| Message-ID | <87h9rxx3g6.fsf@Equus.decebal.nl> |
| In reply to | #89617 |
Op Thursday 30 Apr 2015 11:30 CEST schreef Peter Otten: > Cecil Westerhof wrote: > >> I have a function to fetch a message from a file: >> def get_indexed_message(message_filename, index): >> """ >> Get index message from a file, where 0 gets the first message >> """ >> >> return open(expanduser(message_filename), >> 'r').readlines()[index].rstrip() >> >> What is more the Python way: let the exception fire like this code >> when index is to big, or catching it and returning None? > > Fire an exception, but you may also allow the user to provide a > default. > >> I suppose working zero based is OK. > > Not just OK, it's de rigueur. > > > You didn't ask for that, but > > (1) > > with open(...) as f: > return f.readlines()[index].rstrip() > > is preferrable because it closes the file in a controlled way and I already did that. In another thread I got to know my assumptions where wrong. > (2) you may want to take measures to limit memory usage, e. g. > > assert index >= 0 I put that in, but as first statement. > try: > [line] = itertools.islice(f, index, index+1) > except ValueError: > raise IndexError > return line.rstrip() In my case it is not important. (The biggest file I use has between 100 and 200 lines), but I publish it, so I should do my best to make it so lean as possible. To quote a famous comedian: ‘Learning all the time’. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-04-30 14:28 +0200 |
| Message-ID | <mailman.127.1430396946.3680.python-list@python.org> |
| In reply to | #89622 |
Cecil Westerhof wrote: >> (2) you may want to take measures to limit memory usage, e. g. >> >> assert index >= 0 > > I put that in, but as first statement. For the record, this was not a recommended check, but rather a way to communicate to the reader of my code that unlike yours it doesn't support negative indices. >> try: >> [line] = itertools.islice(f, index, index+1) >> except ValueError: >> raise IndexError >> return line.rstrip() > > In my case it is not important. (The biggest file I use has between > 100 and 200 lines), but I publish it, so I should do my best to make > it so lean as possible. If you keep your return f.readlines()[index] anyway you might allow for negative indices, and then get_indexed_message(message_filename, -1) fetches the last message in the file and get_indexed_message(message_filename, slice(None, None)) fetches a list with all messages.
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-04-30 16:53 +0200 |
| Message-ID | <87sibhvf9k.fsf@Equus.decebal.nl> |
| In reply to | #89627 |
Op Thursday 30 Apr 2015 14:28 CEST schreef Peter Otten: > Cecil Westerhof wrote: > >>> (2) you may want to take measures to limit memory usage, e. g. >>> >>> assert index >= 0 >> >> I put that in, but as first statement. > > For the record, this was not a recommended check, but rather a way > to communicate to the reader of my code that unlike yours it doesn't > support negative indices. > >>> try: >>> [line] = itertools.islice(f, index, index+1) >>> except ValueError: >>> raise IndexError >>> return line.rstrip() >> >> In my case it is not important. (The biggest file I use has between >> 100 and 200 lines), but I publish it, so I should do my best to >> make it so lean as possible. > > If you keep your > > return f.readlines()[index] > > anyway you might allow for negative indices, and then > > get_indexed_message(message_filename, -1) > > fetches the last message in the file and > > get_indexed_message(message_filename, slice(None, None)) > > fetches a list with all messages. It is even possible without keeping it. I can fetch the number of messages and implement it myself without a possible high memory overhead. Certainly something to think about. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-04-30 14:22 +0200 |
| Message-ID | <878ud9x0un.fsf@Equus.decebal.nl> |
| In reply to | #89622 |
Op Thursday 30 Apr 2015 13:26 CEST schreef Cecil Westerhof:
>> try:
>> [line] = itertools.islice(f, index, index+1)
>> except ValueError:
>> raise IndexError
>> return line.rstrip()
>
> In my case it is not important. (The biggest file I use has between
> 100 and 200 lines), but I publish it, so I should do my best to make
> it so lean as possible.
Implemented and pushed to:
https://github.com/CecilWesterhof/PythonLibrary/blob/master/filebasedMessages.py
Did some other optimisation's also. The function get_random_message
now calls get_indexed_message. Saves memory (on the old
implementation) and is more DRY.
I also enhanced get_nr_of_messages:
def get_nr_of_messages(message_filename):
i = -1
with open(expanduser(message_filename), 'r') as f:
for i, l in enumerate(f):
pass
return i + 1
Or can that be done better?
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-04-30 14:05 +0200 |
| Message-ID | <6844153.DioSdhvfDQ@PointedEars.de> |
| In reply to | #89610 |
Cecil Westerhof wrote: > I have a function to fetch a message from a file: > def get_indexed_message(message_filename, index): > """ > Get index message from a file, where 0 gets the first message > """ > > return open(expanduser(message_filename), > 'r').readlines()[index].rstrip() > > What is more the Python way: let the exception fire like this code > when index is to big, or catching it and returning None? It is not only the Python way, it is the *correct* way to throw/_raise_ an exception if the language allows it. Think of what “exception” means: there is an *exceptional* (not normal) circumstance that causes execution of the function/method to stop. Return values and status values to indicate such errors were used before exceptions, and are still used in languages that do not have exceptions. But return values only work if you can tell them apart from success values. You have only one error condition now. If you have a different error condition in the future, you need a different return value for that to tell it apart from the first error condition. There comes a point where you are out of new return values for new error conditions such that you cannot tell them apart from success values anymore. And functions setting status values to refine return values are not reentrant. But you can always throw a different type of exception or the same type of exception with a different message. > I suppose working zero based is OK. Yes, it is the common approach. -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2015-04-30 14:30 +0200 |
| Message-ID | <mailman.128.1430397102.3680.python-list@python.org> |
| In reply to | #89610 |
Op 30-04-15 om 09:43 schreef Cecil Westerhof: > I have a function to fetch a message from a file: > def get_indexed_message(message_filename, index): > """ > Get index message from a file, where 0 gets the first message > """ > > return open(expanduser(message_filename), 'r').readlines()[index].rstrip() > > What is more the Python way: let the exception fire like this code > when index is to big, or catching it and returning None? > > I suppose working zero based is OK. I think this is the wrong question. The right question i: What is the most logical/consistent thing to do, within your project? There are at least two ways to look at this. 1) Getting too large an index is very similar to getting an index with an empty line and can be treated as such. In that case you might prefer to return an empty line. 2) Getting too large an index indicates a problem that can't be handled here. In that case you should let the exception propagate to where it can be handled. 2a) You view the IndexError as a good diagnostic, nothing more to do. 2b) You view the IndexError as an error specific to the implementation and want an exception independent of your implementation: catch the IndexError and raise one you specified yourself. -- Antoon Pardon
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web