What are some other way to rewrite this if block?

S

Santosh Kumar

This simple script is about a public transport, here is the code:

def report_status(should_be_on, came_on):
if should_be_on < 0.0 or should_be_on > 24.0 or came_on < 0.0 or
came_on > 24.0:
return 'time not in range'
elif should_be_on == came_on:
return 'on time'
elif should_be_on > came_on:
return 'early'
elif should_be_on < came_on:
return 'delayed'
else:
return 'something might be wrong'

print(report_status(123, 12.0))

I am looking forward of make the line starting with `if` short.

Any tips are welcome.
 
J

Jussi Piitulainen

Santosh Kumar said:
This simple script is about a public transport, here is the code:

def report_status(should_be_on, came_on):
if should_be_on < 0.0 or should_be_on > 24.0 or came_on < 0.0 or
came_on > 24.0:
return 'time not in range'
elif should_be_on == came_on:
return 'on time'
elif should_be_on > came_on:
return 'early'
elif should_be_on < came_on:
return 'delayed'
else:
return 'something might be wrong'

print(report_status(123, 12.0))

I am looking forward of make the line starting with `if` short.

Any tips are welcome.

A double tip:

if (not (0.0 <= should_be_on <= 24.0) or
not (0.0 <= came_on <= 24.0)):
...

You might want to raise an exception from the range-check branch
instead of returning a value. And raise an exception from the
else-branch, because that branch should never be reached.
 
Y

Yves S. Garret

This simple script is about a public transport, here is the code:



def report_status(should_be_on, came_on):

if should_be_on < 0.0 or should_be_on > 24.0 or came_on < 0.0 or

came_on > 24.0:

return 'time not in range'

elif should_be_on == came_on:

return 'on time'

elif should_be_on > came_on:

return 'early'

elif should_be_on < came_on:

return 'delayed'

else:

return 'something might be wrong'



print(report_status(123, 12.0))



I am looking forward of make the line starting with `if` short.



Any tips are welcome.

If you have a lot of conditions to check, you can't really get around it.
 
J

Jussi Piitulainen

Duncan said:
Or even:

if not (0.0 <= should_be_on <= 24.0 and 0.0 <= came_on <= 24.0):
...

I'd still prefer to split the line, especially considering the fact
that the request was to make the line shorter:

if not (0.0 <= should_be_on <= 24.0 and
0.0 <= came_on <= 24.0):
...
 
S

Steven D'Aprano

This simple script is about a public transport, here is the code:

def report_status(should_be_on, came_on):
if should_be_on < 0.0 or should_be_on > 24.0 or came_on < 0.0 or
came_on > 24.0:
return 'time not in range'
elif should_be_on == came_on:
return 'on time'
elif should_be_on > came_on:
return 'early'
elif should_be_on < came_on:
return 'delayed'
else:
return 'something might be wrong'


Untested, but something like this should work. It adjusts for the times
which fall either side of midnight, it optionally allows for some "slop"
in deciding whether an arrival was on time or not (defaults to 0).


def report(scheduled, actual, slop=0.0):
"""Report whether actual time of arrival is on time, late, early
or cancelled.

Pass actual=None for cancelled services, otherwise both scheduled and
actual must be given as float hours between 0 and 24. E.g. to indicate
a time of 06:30, pass 6.5.

Optional argument slop is a non-negative time in hours which services
are allowed to be late or early and still count as "on time". E.g. if
a service is allowed to arrive with two minutes either side of the
scheduled time and still count as on time, pass slop=2.0/60. The slop
defaults to 0.0.

"""
if not 0 <= scheduled < 24:
raise ValueError('scheduled time out of range')
if not 0 <= slop < 24:
raise ValueError('slop out of range')
if actual is None:
return "service cancelled"
if not 0 <= actual < 24:
raise ValueError('actual arrival time out of range')
diff = actual - scheduled
# Adjust for discontinuity around midnight. We assume that arrivals
# are never more than 12 hours away from their scheduled times.
if diff < -12:
# For example, scheduled=23:55, actual=00:05 gives diff of -23:50
diff += 24
elif diff > 12:
diff -= 24
if diff < -slop:
return "early"
elif diff > slop:
return "late"
else:
return "on time"


One disadvantage with the function as written is that you have to give
times as floats between 0 and 24, instead of a more natural HH:MM syntax.
For example, 11:07am would have to be given as 11.116666666666667.

Another weakness is that any slop allowance is symmetrical (e.g. you
can't allow trains to arrive up to one minute early or five minutes late
to be counted as "on time", the two figures have to be equal).

A third weakness is that you can't allow for arrivals more than 12 hours
early or late.


I am looking forward of make the line starting with `if` short.

:)
 
C

Chris Angelico

A third weakness is that you can't allow for arrivals more than 12 hours
early or late.

Oh, but that'll NEVER happen.

Oh wait, I've been on a service that was 12 hours late.

Is there any chance that you could do your times of arrival and
expectation in, say, integer seconds since 1970?

ChrisA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top