Waht do you think about my repeated_timer class
2QdxY4RzWzUUiLuE at potatochowder.com
2QdxY4RzWzUUiLuE at potatochowder.com
Wed Feb 2 23:27:24 EST 2022
On 2022-02-03 at 15:07:22 +1100,
Chris Angelico <rosuav at gmail.com> wrote:
> On Thu, 3 Feb 2022 at 14:52, <2QdxY4RzWzUUiLuE at potatochowder.com> wrote:
> >
> > On 2022-02-03 at 12:39:43 +1100,
> > Cameron Simpson <cs at cskk.id.au> wrote:
> >
> > > You have:
> > >
> > > def _check_interval(self, interval):
> > > if not type(interval) in [int, float]:
> > > raise TypeError('{} is not numeric'.format(interval))
> > >
> > > This check is better written:
> > >
> > > if not isinstance(interval, (int,float)):
> > >
> > > which handles subclasses of these types (but note that bool subclasses
> > > int :-) normally we don't care), or behaviourally:
> > >
> > > try:
> > > interval = float(interval)
> > > except ValueError as e:
> > > raise TypeError(
> > > "cannot convert %s:%r to float: %s"
> > > % (type(interval).__name__, interval, e)) from e
> > >
> > > which tries to convert to float and fails if that does not work, which
> > > supports classes with a __float__ method (these classes are rare, but
> > > decimal.Decimal is one example).
> >
> > I think this can be simplified for time intervals to the following:
> >
> > if interval <= 0:
> > raise ValueError(...)
>
> That's checking something quite different, though. Casting to float
> will accept anything that can be, well, cast to float, but checking
> for less than or equal to zero demands that it already be some sort of
> number. It's debatable which check is more correct, but certainly this
> is not a simplification of the other code, it's a distinctly different
> validation.
Okay, "simplified" isn't quite the right word. Given two examples (with
known deficiencies) and no actual use cases or specifications, I added a
third example, which I believed was simpler (and arguably better in one
or more ways, which I explained), than the others.
> > which accepts non-negative real values; throws ValueError for negative
> > real values; and TypeError for other stuff, including complex numbers
> > (pathological types notwithstanding). One thing that doesn't work right
> > is NaNs, but I'm sure it's not the only code that acts weirdly when
> > faced with a NaM (curiously, Timer accepts a NaN, but the text I get
> > from help(Timer) in Python 3.10.2 is, well, broken).
>
> Strange. The text I get in 3.11.0a1 is fine. But in any case, there's
> always the docs on the web.
>
> https://docs.python.org/3/library/threading.html#timer-objects
help(Timer) is built into my REPL (and likely consumed by development
systems and IDEs everywhere). No web necessary.
> > FWIW, I'd find some way to tell users the units (seconds, milliseconds,
> > fortnights, etc.) instead of making them wade through your code to find
> > the call to (and possibly the [broken] help text of) Timer.
>
> In anything in Python, assume that the unit is seconds. With anything
> that accepts floats (where these can be distinguished from integers),
> assume the unit is seconds. If it accepts micro or nanoseconds, it'll
> almost certainly be called "high resolution timer" (unless it accepts
> two args, sec and us/ns, but that's pretty obvious), so you can
> generally exclude those too. The only real question is whether
> sleep(int) takes seconds or milliseconds, which isn't a problem here.
>
> Citation: I've slept in many many programming languages and
> frameworks. Which sounds seriously weird, but you're all programmers,
> you know what I mean :)
I've slept in enough programming environments to know better than to
assume anything. ;-)
More information about the Python-list
mailing list