[Tutor] How (not!) lengthy should functions be?

boB Stepp robertvstepp at gmail.com
Sat Apr 18 21:01:19 CEST 2015


On Thu, Apr 16, 2015 at 1:43 PM, Peter Otten <__peter__ at web.de> wrote:

> However, there's more to it. You are working in an environment where people
> may be harmed if you get your numbers wrong, and nothing hinders you to swap
> the arguments in your percent2Gy() function or even pass it a length and an
> amount of dollars. You need measures to make this unlikely.

I am attempting to do this. In a large sense, the whole purpose of my
program is to evaluate what the planner has already done. The planner
at this point would normally believe he has a deliverable plan that
satisfies everything his physician requires. At this point he would
normally have the physician review his plan and approve it. The
planner has this degree of certainty at this point. The point of this
program is to provide additional checking to ensure nothing has been
overlooked by the planner before he presents the plan to the
physician. The program changes nothing in his plan. It is just a
reader of existing plan data and then evaluates it against a variety
of criteria. The planner *should* have already done this process
himself. The program merely double-checks everything (And adds
additional checking that I believe should be done, but not necessarily
all of my colleagues agree with me on this.).

> Unambiguous function names and keyword-only parameters (not available in
> Python 2) and of course tests help, but you might also consider custom types
> that are restricted to a well-defined set of operations. A sketch:

I do check the numbers and units both for falling within a proper
range of allowed values and correct associated units for what is being
measured. This happens at several places, but not every place where
the information is is used. But data is checked as it enters the
workflow and at multiple points during the program's workflow and
finally at the end result. Since I am not writing classes yet I am not
taking this approach yet. But I see a greater value in doing it this
way as the information would be constantly checked for validity.

> # For illustration purpose only!
> class Percent:
>     def __init__(self, value):
>         if value < 1 or value > 100: # XXX allow 0%?
>             raise ValueError
>         self.value = value
>     def factor(self):
>         return self.value / 100.0
>     def __repr__(self):
>         return "{} %".format(self.value)

Something like this would have to be tweaked depending on what
structure and what parameter is being evaluated. Actual dose to
*something* in the patient can vary between 0% (For something
receiving essentially no dose--far from the area of treatment.) to the
value of point of maximum dose, which, for an SBRT-type plan, could be
as high as 160% of prescription dose. Of course such high doses are
only allowed to occur within the confines of the tumor being treated
(NEVER outside of it!).

[...]

>     target_dose.partial_dose(0.1) # raises TypeError
>
> Output:
>
> $ python gray.py
> 20 Gy
> 2.0 Gy
> 2.0 Gy # 10 % of the target dose
> Traceback (most recent call last):
>   File "gray.py", line 43, in <module>
>     target_dose.partial_dose(0.1) # raises TypeError
>   File "gray.py", line 27, in partial_dose
>     raise TypeError
> TypeError

I generate an output very similar to this except I must get the error
to show up in the planning system software. I rephrase the error
message into language that the planner will understand that makes
sense in the context of his plan. If it is an issue with his plan, he
will know exactly what the issue is and how to address it.

For errors that indicate an issue with my coding the planner would
receive a message that states where within the program the error
occurred, using language that will make sense to the planner, but also
pinpoint exactly where the error was generated. And to contact me
immediately with the issue.

> OK, I got carried away a bit with my example, but you might get an idea
> where I'm aiming at. The way I wrote it it is pretty clear that Percent(10)
> denote 10 rather than 1000 %.

Amen!

> I can't spare you a last remark: Python may not be the right language to
> make this bulletproof.

Would you elaborate on this? I am sure I don't have the experience
with programming and programming languages to truly understand your
point.

As I final note I want to emphasize that I am not writing a program to
*create* a treatment plan. Nor am I writing a program that can *alter*
an existing treatment plan. It is merely reading output from the
treatment plan and evaluating that output against agreed upon best
practice numbers. If this program never gets implemented it will
change nothing in how plans are created and implemented. If it does
get implemented, then the planner will do what he would have done
anyway in the absence of the program. However, if the program flags
something for his attention, then something will get  noticed that
might not have. I wish to emphasize that most of these *somethings*
would not be actual errors that would cause any harm to a patient;
instead, it would suggest ways the planner can make his viable
treatment plan even better: Improve target coverage even more; notice
that organ x's sparing could be improved without decreasing target
coverage; etc. Even though I am attempting to make this program as
*bulletproof* as my knowledge and experience allows, it cannot affect
anyone's treatment. It is purely a supplemental level of checking,
much like the many, ... , many human checks that we already implement.
And this feedback, whether human or program-based, is to make a good
plan even better, which will result in even better patient outcomes.

boB


More information about the Tutor mailing list